您的位置:首页 > 其它

ZOJ3635——Cinema in Akiba(树状数组+二分)

2014-09-07 11:52 441 查看


Description

Cinema in Akiba (CIA) is a small but very popular cinema in Akihabara. Every night the cinema is full of people. The layout of CIA is very interesting,
as there is only one row so that every audience can enjoy the wonderful movies without any annoyance by other audiences sitting in front of him/her.
The ticket for CIA is strange, too. There are n seats in CIA and they are numbered from 1 to n in order. Apparently, n tickets
will be sold everyday. When buying a ticket, if there are k tickets left, your ticket number will be an integer i (1 ≤ i ≤ k), and you should choose the ith empty
seat (not occupied by others) and sit down for the film.
On November, 11th, n geeks go to CIA to celebrate their anual festival. The ticket number of the ith geek is ai.
Can you help them find out their seat numbers?


Input

The input contains multiple test cases. Process to end of file.

The first line of each case is an integer n (1 ≤ n ≤ 50000), the number of geeks as well as the number of seats in CIA. Then follows a line containing nintegers a1, a2,
..., an (1 ≤ ai ≤ n - i +
1), as described above. The third line is an integer m (1 ≤ m ≤ 3000), the number of queries, and the next line is mintegers, q1, q2,
..., qm (1 ≤ qi ≤ n),
each represents the geek's number and you should help him find his seat.


Output

For each test case, print m integers in a line, seperated by one space. The ith integer is the seat number of the qith geek.


Sample Input

3
1 1 1
3
1 2 3
5
2 3 3 2 1
5
2 3 4 5 1


Sample Output

1 2 3
4 5 3 1 2


题意:

有一些人来电影院,他们按照顺序买票,每张票上有一个数字ai,代表他应当坐到第ai个空位上。

现在给出一定的询问。对于每个询问qi,输出第qi个买票人坐的位置。

分析:

假设现在前面已经有一些人买票入座了,那么后面的人买票之后要找到他所对应的位置比较好的办法就是二分查找。

但是二分查找的前提是序列单调,而且数组同时又是动态更新的,所以很自然的想到了树状数组。

树状数组可以求出某个位置之前共有多少空位。然后二分就可以找到目标位置。开一个数组记录每个人的位置。并且入座后跟新树状数组即可。

#include <algorithm>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <iostream>
#define INF 0x7fffffff
using namespace std;

typedef long long LL;
const int N = 5e4 + 10;

int a
,q
,c
,n;

int lowbit(int x)
{
    return x&-x;
}
void update(int x,int v)
{
    for(int i=x;i<=n;i+=lowbit(i))
        a[i]+=v;
    return;
}
int getsum(int x)
{
    int sum=0;
    for(int i=x;i>0;i-=lowbit(i))
        sum+=a[i];
    return sum;
}
int main()
{
    int m;
    while(scanf("%d",&n)!=EOF)
    {
        memset(a,0,sizeof(a));
        memset(q,0,sizeof(q));
        for(int i=1;i<=n;i++)
        {
            int x;
            scanf("%d",&x);
            int l=1,r=n,mid;
            while(l<r)
            {
                mid=(l+r+1)/2;
                int t=mid-getsum(mid-1);
                if(t>x)
                    r=mid-1;
                else if(t<=x) l=mid;
            }
            q[i]=l;
            update(l,1);
        }
        scanf("%d",&m);
        for(int i=0;i<m;i++)
        {
            int x;
            scanf("%d",&x);
            if(i==m-1) printf("%d\n",q[x]);
            else printf("%d ",q[x]);
        }
    }

    return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: