这里只需要维护前k个相同的数出现的位置即可(不存在记为0),查找的时候找钱的k个相同的数在区间 [ 0 , l − 1 ] [0,l-1] [0,l−1]的数有几个
#pragma GCC optimize(2)
#pragma GCC optimize(3,"Ofast","inline")
#include <bits/stdc++.h>
#define inf 0x7fffffff
#define ll long long
//#define int long long
//#define double long double
#define re register int
#define void inline void
#define eps 1e-8
//#define mod 1e9+7
#define ls(p) p<<1
#define rs(p) p<<1|1
#define pi acos(-1.0)
#define pb push_back
#define P pair < int , int >
#define mk make_pair
using namespace std;
const int mod=998244353;
const int M=1e9;
const int N=1e5+5;//?????????? 4e8
vector < int > pos[N];
struct node
{
int l,r,sum;
}e[N*20];
int tot,rt[N];
int n,k,q;
void insert(int &p,int pre,int l,int r,int d)
{
e[++tot]=e[pre];
p=tot;
e[p].sum++;
if(l==r) return;
int mid=(l+r)>>1;
if(d<=mid) insert(e[p].l,e[pre].l,l,mid,d);
else insert(e[p].r,e[pre].r,mid+1,r,d);
}
int ask(int L,int R,int l,int r,int d)
{
if(r<=d) return e[R].sum-e[L].sum;
int mid=(l+r)>>1;
int ans=0;
if(d>mid) ans+=ask(e[L].r,e[R].r,mid+1,r,d);
return ans+ask(e[L].l,e[R].l,l,mid,d);
}
void solve()
{
cin>>n>>k;
for(re i=1;i<=n;i++)
{
int x,p,sz;
scanf("%d",&x);
pos[x].pb(i);
sz=pos[x].size();
if(sz<=k) p=0;
else p=pos[x][sz-1-k];
insert(rt[i],rt[i-1],0,n,p);
}
cin>>q;
int ans=0;
while(q--)
{
int l,r;
scanf("%d%d",&l,&r);
l=(l+ans)%n+1;
r=(r+ans)%n+1;
if(l>r) swap(l,r);
ans=ask(rt[l-1],rt[r],0,n,l-1);
printf("%d\n",ans);
}
}
signed main()
{
int T=1;
// cin>>T;
for(int index=1;index<=T;index++)
{
// printf("Case %d:\n",index);
solve();
// puts("");
}
return 0;
}
/*
1
6
URLLDR
*/