Codeforces Round #567 (Div. 2)D - Irrigation【BIT】+【乱搞】

D. Irrigation

time limit per test

2.5 seconds

memory limit per test

512 megabytes

input

standard input

output

standard output

Misha was interested in water delivery from childhood. That's why his mother sent him to the annual Innovative Olympiad in Irrigation (IOI). Pupils from all Berland compete there demonstrating their skills in watering. It is extremely expensive to host such an olympiad, so after the first nn olympiads the organizers introduced the following rule of the host city selection.

The host cities of the olympiads are selected in the following way. There are mm cities in Berland wishing to host the olympiad, they are numbered from 11 to mm. The host city of each next olympiad is determined as the city that hosted the olympiad the smallest number of times before. If there are several such cities, the city with the smallest index is selected among them.

Misha's mother is interested where the olympiad will be held in some specific years. The only information she knows is the above selection rule and the host cities of the first nn olympiads. Help her and if you succeed, she will ask Misha to avoid flooding your house.

Input

The first line contains three integers nn, mm and qq (1≤n,m,q≤5000001≤n,m,q≤500000) — the number of olympiads before the rule was introduced, the number of cities in Berland wishing to host the olympiad, and the number of years Misha's mother is interested in, respectively.

The next line contains nn integers a1,a2,…,ana1,a2,…,an (1≤ai≤m1≤ai≤m), where aiai denotes the city which hosted the olympiad in the ii-th year. Note that before the rule was introduced the host city was chosen arbitrarily.

Each of the next qq lines contains an integer kiki (n+1≤ki≤1018n+1≤ki≤1018) — the year number Misha's mother is interested in host city in.

Output

Print qq integers. The ii-th of them should be the city the olympiad will be hosted in the year kiki.

Examples

input

Copy

6 4 10
3 1 1 1 2 2
7
8
9
10
11
12
13
14
15
16

output

Copy

4
3
4
2
3
4
1
2
3
4

input

Copy

4 5 4
4 4 5 1
15
9
13
6

output

Copy

5
3
3
3

Note

In the first example Misha's mother is interested in the first 1010 years after the rule was introduced. The host cities these years are 4, 3, 4, 2, 3, 4, 1, 2, 3, 4.

In the second example the host cities after the new city is introduced are 2, 3, 1, 2, 3, 5, 1, 2, 3, 4, 5, 1.

 

 

分析:用f[i]表示所有城市都至少举办了i次的时间(即把所有举办次数小于i的都加到i),对于每个k值,找到最大的小于它的f[i],令left = k - f[i],然后再找出所有城市里举办次数小于i次的,然后按照其id排序后的第 left 个城市,就是k对应的城市。

对于f[i]数组可以直接线性预处理,对于left值可以直接二分查找,问题在于如何找出“所有城市里举办次数小于i次的,然后按照其id排序后的第 left 个城市”。

比较容易想到的一个暴力离线做法,将k排序后遍历,对于每次查询,将小于i的城市放入一个集合中,然后暴力找集合中的第left小。这样的复杂度是O(qmlogm)

这里可以用一个bit来优化,对于每次加入的城市,在bit中add,对于其前缀和是一个线性的关系,那么第left个的前缀和一定是left,所以这里直接二分就可以了。复杂度O(q(logm)^2)

#include "bits/stdc++.h"
using namespace std;
struct BIT {
    int n;vector<int> v;
    BIT(int n) : n(n) { v.resize(n + 1); }
    void update(long long x, long long d) { while (x <= n) { v[x] += d;/*if (v[x] >= mod)v[x] -= mod*/;x += (x & -x); }}
    long long que(long long x) { long long res = 0;while (x > 0) { res += v[x];/*if (res >= mod)res -= mod*/;x -= (x & -x); }return res; }
};
BIT bit(500000);

int a[500004];
struct node
{
    int id;
    long long k;
    bool friend operator < (node a,node b){
        return a.k<b.k;
    }
}b[500004];
struct p{
    int id,w;
    bool friend operator < (p a, p b){
        if(a.w==b.w)return a.id<b.id;
        return a.w<b.w;
    }
}c[500004];
long long f[500004];
long long times[500004];
int ans [500004];
int main() {
    int n,m,q;
    cin>>n>>m>>q;
    long long maxi = 0;
    for (int i = 1; i <= n; ++i)scanf("%d",&a[i]),times[a[i]]++;
    for (int i = 1; i <= m; ++i)c[i]={i,times[i]};
    sort(c+1,c+1+m);
    for (int i = 1; i <= m; ++i)times[i]=c[i].w,maxi = max(maxi,times[i]);
    for (int i = 1; i <= m; ++i)f[times[i]+1]++;
    for (int i = 1; i <= maxi; ++i)f[i]+=f[i-1];
    for (int i = 1; i <= maxi; ++i)f[i]+=f[i-1];
    for (int i = 0; i < q; ++i)scanf("%lld",&b[i].k), b[i].k-=n, b[i].id=i;
    sort(b,b+q);
    int P=0;
    for (int i = 0; i < q; ++i) {
        long long k = b[i].k;
        int pos = lower_bound(f+1,f+maxi+1,k)-f-1;
        if(k>f[maxi]){
            long long left = (k - f[maxi]) % m;
            if(left ==0)left = m;
            ans[b[i].id]=left;
        }
        else {
            long long left = k - f[pos];
            int pos2 = upper_bound(times+1,times+1+m,pos) - times - 1;
            for (int j = P+1; j <= pos2; ++j) {
                bit.update(c[j].id,1);
            }
            P=pos2;
            int l = 1,r = m;
            int res ;
            while(l<=r){
                int mid = (l+r)>>1;
                if(bit.que(mid)>=left){
                    res = mid;
                    r=mid-1;
                }
                else l = mid+1;
            }
            ans[b[i].id]=res;
        }
    }
    for (int i = 0; i < q; ++i) {
        printf("%d\n",ans[i]);
    }
}

 

  • 4
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值