ZOJ3635——Cinema in Akiba(樹狀數組+二分)

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 a1a2, ..., 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, q1q2, ..., 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[N],q[N],c[N],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;
}



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章