[codeforces813E]Army Creation

time limit per test : 2 seconds
memory limit per test : 256 megabytes

As you might remember from our previous rounds, Vova really likes computer games. Now he is playing a strategy game known as Rage of Empires.

In the game Vova can hire nn different warriors; ii th warrior has the type aia_i. Vova wants to create a balanced army hiring some subset of warriors. An army is called balanced if for each type of warrior present in the game there are not more than kk warriors of this type in the army. Of course, Vova wants his army to be as large as possible.

To make things more complicated, Vova has to consider qq different plans of creating his army. ith plan allows him to hire only warriors whose numbers are not less than li and not greater than rir_i.

Help Vova to determine the largest size of a balanced army for each plan.

Be aware that the plans are given in a modified way. See input section for details.

Input

The first line contains two integers nn and k(1n,k100000)k (1 ≤ n, k ≤ 100000).
The second line contains n integers a1,a2,...an(1ai100000)a_1, a_2, ... a_n (1 ≤ a_i ≤ 100000).
The third line contains one integer q(1q100000)q (1 ≤ q ≤ 100000).
Then qq lines follow. ii th line contains two numbers xix_i and yi which represent ith plan (1xi,yin)(1 ≤ x_i, y_i ≤ n).

You have to keep track of the answer to the last plan (let’s call it last). In the beginning last=0last = 0. Then to restore values of li and ri for the ith plan, you have to do the following:

li=((xi+last)modn)+1l_i = ((x_i + last) mod n) + 1;
ri=((yi+last)modn)+1r_i = ((y_i + last) mod n) + 1;
If li>ril_i > r_i, swap lil_i and rir_i.

Output

Print q numbers. ith number must be equal to the maximum size of a balanced army when considering ith plan.

Example

Input

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

Output

2
4
1
3
2

Note

In the first example the real plans are:

  1. 1 2
  2. 1 6
  3. 6 6
  4. 2 4
  5. 4 6

題意:
給定一個n,k,還有一個長度爲n的數組a1,a2,a3,...,ana_1,a_2,a_3,...,a_naia_i表示第ii個士兵的種類。一個合法的隊伍是保證每一種類的士兵個數不會超過kk,有qq組詢問,每組詢問一個區間,求區間內元素可以組成的最大合法隊伍是多大。強制在線。

題解:
對於每個ii處理出從他往前數第k+1k+1a[i]a[i]的位置,記錄爲pa[i]pa[i],然後對於求答案我們只需要求[l,r][l,r]中,pa[i]<lpa[i]<l的數量即爲答案,這個可以用主席樹解決。

#include<bits/stdc++.h>
#define LiangJiaJun main
using namespace std;
int n,k,q,m,a[100004];
int pa[100004],mk[100004];
int rt[100004];
vector<int>vec[100004];
vector<int>v;
int tot;
struct prt{
    int l,r,w;
}T[100004*20];
int getid(int x){
    return lower_bound(v.begin(),v.end(),x)-v.begin()+1;
}
void build(int &k,int l,int r){
     k=++tot;
     T[k].w=0;
     if(l==r)return ;
     int mid=(l+r)>>1;
     build(T[k].l,l,mid);
     build(T[k].r,mid+1,r);
}
void update(int l,int r,int &now,int last,int k){
     T[++tot]=T[last];
     now=tot;
     T[now].w++;
     if(l==r)return ;
     int mid=(l+r)>>1;
     if(k<=mid)update(l,mid,T[now].l,T[last].l,k);
     else update(mid+1,r,T[now].r,T[last].r,k);
}
int query(int l,int r,int x,int y,int k){
    if(l==r)return T[y].w-T[x].w;
    int mid=(l+r)>>1;
    if(k<=mid)return query(l,mid,T[x].l,T[y].l,k);
    else{
        int ret=0;
        ret+=T[T[y].l].w-T[T[x].l].w;
        ret+=query(mid+1,r,T[x].r,T[y].r,k);
        return ret;
    }
}
int LiangJiaJun(){
    tot=0;
    memset(rt,0,sizeof(rt));
    for(int i=0;i<=100000;i++)vec[i].clear();
    scanf("%d%d",&n,&k);
    for(int i=1;i<=n;i++){
        scanf("%d",&a[i]);
        vec[a[i]].push_back(i);
        mk[i]=vec[a[i]].size()-1;
    }
    for(int i=1;i<=n;i++){
        if(mk[i]>=k){
            pa[i]=vec[a[i]][mk[i]-k];
        }
        else{
            pa[i]=0;
        }
        v.push_back(pa[i]);
    }
    sort(v.begin(),v.end());
    v.erase(unique(v.begin(),v.end()),v.end());
    build(rt[0],1,n);
    for(int i=1;i<=n;i++){
        update(1,n,rt[i],rt[i-1],getid(pa[i]));
    }
    scanf("%d",&q);
    int last=0;
    while(q--){
        int l,r,k;
        scanf("%d%d",&l,&r);
        l=((l+last)%n+1);
        r=((r+last)%n+1);
        if(l>r)swap(l,r);
        k=upper_bound(v.begin(),v.end(),l-1)-v.begin();
        last=query(1,n,rt[l-1],rt[r],k);
        printf("%d\n",last);
    }
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章