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;
}

posted on 2012-08-26 21:36  aigoruan  阅读(210)  评论(0)    收藏  举报

导航