题意:大概就是说有一些票,编号代表只能坐从左往右第i个空座。每个人按序买了票,问最后他们都做哪个座位。
思路:比较经典的模型,类似于约瑟夫环。首先将树状数组所有数字置1,每次二分前缀和得到第k个位置,该票被买走意味着将该位置数字置0。如此可以。
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <vector>
#include <map>
#include <queue>
using namespace std;
typedef long long LL;
const int maxn=50005;
int n;
struct BIT
{
int dat[maxn];
void clear()
{
memset(dat,0,sizeof(dat));
}
int lowbit(int x)
{
return -x&x;
}
int getSum(int x)
{
int s=0;
while(x>0)
{
s+=dat[x];
x-=lowbit(x);
}
return s;
}
void add(int x,int v)
{
while(x<=n)
{
dat[x]+=v;
x+=lowbit(x);
}
}
};
BIT tree;
int q[maxn];
int binSearch(int low,int high,int sum)
{
int mid=low+(high-low)/2;
while(low<high)
{
if(tree.getSum(mid)>=sum)
high=mid;
else
low=mid+1;
mid=low+(high-low)/2;
}
return mid;
}
int main()
{
while(scanf("%d",&n)!=EOF)
{
tree.clear();
for(int i=1; i<=n; ++i)
tree.add(i,1);
for(int i=1; i<=n; ++i)
{
int a;
scanf("%d",&a);
q[i]=binSearch(1,n,a);
tree.add(q[i],-1);
}
int m;
scanf("%d",&m);
for(int i=0; i<m; ++i)
{
int x;
scanf("%d",&x);
if(i!=0) printf(" ");
printf("%d",q[x]);
}
printf("\n");
}
return 0;
}