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 n n n different warriors; i i i th warrior has the type a i a_i ai. 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 k k k 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 q q q 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 r i r_i ri.
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
n
n
n and
k
(
1
≤
n
,
k
≤
100000
)
k (1 ≤ n, k ≤ 100000)
k(1 ≤ n, k ≤ 100000).
The second line contains n integers
a
1
,
a
2
,
.
.
.
a
n
(
1
≤
a
i
≤
100000
)
a_1, a_2, ... a_n (1 ≤ a_i ≤ 100000)
a1,a2,...an(1 ≤ ai ≤ 100000).
The third line contains one integer
q
(
1
≤
q
≤
100000
)
q (1 ≤ q ≤ 100000)
q(1 ≤ q ≤ 100000).
Then
q
q
q lines follow.
i
i
i th line contains two numbers
x
i
x_i
xi and yi which represent ith plan
(
1
≤
x
i
,
y
i
≤
n
)
(1 ≤ x_i, y_i ≤ n)
(1 ≤ xi, yi ≤ n).
You have to keep track of the answer to the last plan (let’s call it last). In the beginning l a s t = 0 last = 0 last = 0. Then to restore values of li and ri for the ith plan, you have to do the following:
l
i
=
(
(
x
i
+
l
a
s
t
)
m
o
d
n
)
+
1
l_i = ((x_i + last) mod n) + 1
li = ((xi + last)modn) + 1;
r
i
=
(
(
y
i
+
l
a
s
t
)
m
o
d
n
)
+
1
r_i = ((y_i + last) mod n) + 1
ri = ((yi + last)modn) + 1;
If
l
i
>
r
i
l_i > r_i
li > ri, swap
l
i
l_i
li and
r
i
r_i
ri.
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 2
- 1 6
- 6 6
- 2 4
- 4 6
题意:
给定一个n,k,还有一个长度为n的数组
a
1
,
a
2
,
a
3
,
.
.
.
,
a
n
a_1,a_2,a_3,...,a_n
a1,a2,a3,...,an,
a
i
a_i
ai表示第
i
i
i个士兵的种类。一个合法的队伍是保证每一种类的士兵个数不会超过
k
k
k,有
q
q
q组询问,每组询问一个区间,求区间内元素可以组成的最大合法队伍是多大。强制在线。
题解:
对于每个
i
i
i处理出从他往前数第
k
+
1
k+1
k+1个
a
[
i
]
a[i]
a[i]的位置,记录为
p
a
[
i
]
pa[i]
pa[i],然后对于求答案我们只需要求
[
l
,
r
]
[l,r]
[l,r]中,
p
a
[
i
]
<
l
pa[i]<l
pa[i]<l的数量即为答案,这个可以用主席树解决。
#include<bits/stdc++.h>
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 main(){
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;
}