ZOJ 3635 Cinema in Akiba(树状数组 + 二分)

来源:互联网 发布:linux内核编译 ubuntu 编辑:程序博客网 时间:2024/05/17 08:04

题目链接:Click here~~

题意:

有 n 个位置,从小到大分别编号为 1~n。然后有 n 次操作,每次取第 Ki 个没有被取到的编号,最后询问某次操作取出的是谁。

解题思路:

用 sum(i) 记录 1~i 位置中,一共有几个空座位。每次二分找到第 Ki 个是哪一个,然后将这个位置 th~n 全部减一。

#include <vector>#include <string>#include <stdio.h>#include <string.h>#include <algorithm>using namespace std;const int N = 5e4 + 5;int c[N],ans[N];int lowbit(int x){    return x & -x;}void add(int loc,int x){    while(loc < N)    {        c[loc] += x;        loc += lowbit(loc);    }}int sum(int loc){    int ret = 0;    while(loc)    {        ret += c[loc];        loc -= lowbit(loc);    }    return ret;}int main(){    int n;    while(~scanf("%d",&n))    {        memset(c,0,sizeof(c));        for(int i=1;i<=n;i++)            add(i,1);        for(int i=1;i<=n;i++)        {            int k;            scanf("%d",&k);            int l = 1 , r = n;            while(l < r)            {                int mid = l+r >> 1;                if(sum(mid) < k)                    l = mid + 1;                else                    r = mid;            }            ans[i] = r;            add(r,-1);        }        int Q,m;        scanf("%d",&Q);        while(Q--)        {            scanf("%d",&m);            printf("%d%c",ans[m],Q?' ':'\n');        }    }    return 0;}


原创粉丝点击