I. partitioned
The core is to find out what to maintain. Imagine that in a column of numbers, we take out the same group. We need to take no more than k numbers within a given range. If the violence is judged from left to right and the number is recorded, it is not realistic. Then we will open an array to record whether the number of positions + K in this group will exceed the number of this group, but the key to statistics later is not "from left to right". If the number + k is still in the range, we will not make a record, because there will be many restrictions, and the middle block is not easy to ask, so it is easy to make mistakes (but maybe it can be written). We can change our thinking and focus on the ones that are larger than the boundary after + K, which means that we won't take more than k, so ans + +; then we can divide them into blocks, one by one on both sides, and use dichotomy in the middle to find the ones that are larger than the boundary, so we need sort preprocessing.
//I'm the only one who can understand the untidy explanation.~~
<( ̄︶ ̄)↗[GO!]
1 #include<bits/stdc++.h> 2 #include<iostream> 3 #include<stack> 4 #include<algorithm> 5 #include<cstdio> 6 #include<cmath> 7 #include<cstring> 8 #define mem(a) memset(a,0,sizeof(a)) 9 #define ll long long 10 #define mp make_pair 11 #define pb push_back 12 #define inf 0x3f3f3f3f 13 using namespace std; 14 const int N=1e5+5; 15 int n,blo,num,belong[N],l[N],r[N],d[N],a[N],b[N],mx=0,k; 16 int nx[N]; 17 vector<int>cnt[N]; 18 void build() 19 { 20 blo=sqrt(n); 21 num=n/blo; 22 if(n%blo) num++; 23 for(int i=1;i<=n;i++) 24 { 25 belong[i]=((i-1)/blo)+1; 26 b[i]=nx[i]; 27 } 28 for(int i=1;i<=num;i++) 29 { 30 l[i]=(i-1)*blo+1; 31 r[i]=i*blo; 32 } 33 r[num]=n; 34 for(int i=1;i<=num;i++) 35 sort(b+l[i],b+r[i]+1); 36 } 37 int query(int x,int y) 38 { 39 int ans=0; 40 for(int i=x;i<=min(r[belong[x]],y);i++) 41 if(nx[i]>y) ans++; 42 if(belong[x]!=belong[y]) 43 { 44 for(int i=l[belong[y]];i<=y;i++) 45 if(nx[i]>y) ans++; 46 for(int i=belong[x]+1;i<=belong[y]-1;i++) 47 { 48 int j=b+r[i]+1-upper_bound(b+l[i],b+r[i]+1,y); 49 ans+=j; 50 } 51 } 52 return ans; 53 } 54 int main() 55 { 56 scanf("%d%d",&n,&k); 57 for(int i=1;i<=n;i++) 58 { 59 scanf("%d\n",&a[i]); 60 mx=max(mx,a[i]); 61 } 62 for(int i=1;i<=n;i++) 63 cnt[a[i]].pb(i); 64 for(int i=1;i<N;i++) 65 { 66 for(int j=0;j<cnt[i].size();j++) 67 { 68 if(j+k>=cnt[i].size()) 69 nx[cnt[i][j]]=N; 70 else 71 nx[cnt[i][j]]=cnt[i][j+k]; 72 } 73 } 74 build(); 75 int last=0,m; 76 scanf("%d",&m); 77 while(m--) 78 { 79 int ans=0; 80 int L,R; 81 scanf("%d%d",&L,&R); 82 L=(L+last)%n+1; 83 R=(R+last)%n+1; 84 if(L>R)swap(L,R); 85 if(R-L+1<=k) ans=R-L+1; 86 else ans=query(L,R); 87 printf("%d\n",ans); 88 last=ans; 89 } 90 build(); 91 92 }