ZOJ Monthly, August 2012 3635 Cinema in Akiba
http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3635
题意:先给一个数列1、2、3……n。然后求第k小,并将它删除。
思路:树状数组+二分 模板
View Code
#include<stdio.h> #include<string.h> #include<iostream> #define lowbit(x) (x)&(-x) using namespace std; const int maxn = 100005; int n,sum[1<<20]; int as[maxn]; void add(int x,int v){for(;x<=n;x+=lowbit(x))sum[x]+=v;} int getsum(int x){int v=0;for(;x;x-=lowbit(x))v+=sum[x];return v;} int findk(int k) { int pos = 0,cnt = 0; for(int i = 19; i >= 0; -- i){ pos += (1<<i); if(pos>=n || cnt+sum[pos]>=k) pos -= (1<<i); else cnt += sum[pos]; }return pos + 1; } int main() { int i,j,m; while(scanf("%d",&n)==1){ for(i = 1; i <= n; ++ i)add(i,1); for(i = 1; i <= n; ++ i){ scanf("%d",&j); as[i] = findk(j); add(as[i],-1); } scanf("%d",&m); while(m--){ scanf("%d",&j); printf("%d%c",as[j],m?' ':'\n'); } } return 0; }

浙公网安备 33010602011771号