给你n和k,n个数,每个数范围1e5,m次查询,每次查询区间(l,r),在区间中的每个数,如果超过k次只算k次,否则算原来的次数,求总次数,强制在线
解法:线段树维护区间中每个数经过k次到达的点pos,然后其中pos<=r的就是能满足条件的加到答案上即可
因为假设原来的点是x(l<=x<=r),经过k次是pos(l<=pos<=r),那么此时我们不能同时算这两个点的贡献,所以只需要算后一个点的贡献,当pos的经过k次到达的点也<=r时,那么pos点也不能算进来,以此类推
线段树每个区间维护一个vector,vector要sort一下,然后查询lowerbound,复杂度O(nlognlogn)

//#pragma comment(linker, "/stack:200000000") //#pragma GCC optimize("Ofast,no-stack-protector") //#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native") //#pragma GCC optimize("unroll-loops") #include<bits/stdc++.h> #define fi first #define se second #define mp make_pair #define pb push_back #define pi acos(-1.0) #define ll long long #define mod 1000000007 #define C 0.5772156649 #define ls l,m,rt<<1 #define rs m+1,r,rt<<1|1 #define pil pair<int,ll> #define pii pair<int,int> #define ull unsigned long long #define base 1000000000000000000 #define fio ios::sync_with_stdio(false);cin.tie(0) using namespace std; const double g=10.0,eps=1e-9; const int N=2000000+10,maxn=100000+10,inf=0x3f3f3f3f,INF=0x3f3f3f3f3f3f3f3f; int a[maxn],ans[maxn],num[maxn]; int Next[maxn],id[maxn]; vector<int>v[N]; void pushup(int rt) { v[rt].clear(); // v[rt].resize(v[rt<<1].size()+v[rt<<1|1].size()); for(int i=0;i<v[rt<<1].size();i++) v[rt].pb(v[rt<<1][i]); for(int i=0;i<v[rt<<1|1].size();i++) v[rt].pb(v[rt<<1|1][i]); sort(v[rt].begin(),v[rt].end()); } void build(int l,int r,int rt) { if(l==r) { v[rt].pb(ans[l]); return ; } int m=(l+r)>>1; build(ls);build(rs); pushup(rt); } int query(int L,int R,int l,int r,int rt) { if(L<=l&&r<=R) { // for(int i=0;i<v[rt].size();i++) // printf("%d ",v[rt][i]); int p=upper_bound(v[rt].begin(),v[rt].end(),R)-v[rt].begin(); return p; } int m=(l+r)>>1,ans=0; if(L<=m)ans+=query(L,R,ls); if(m<R)ans+=query(L,R,rs); return ans; } int main() { int n,k; scanf("%d%d",&n,&k); for(int i=1;i<=n;i++) { scanf("%d",&a[i]); ans[i]=id[i]=n+1; } for(int i=n;i>=1;i--) { Next[i]=id[a[i]]; id[a[i]]=i; } memset(id,0,sizeof id); for(int i=n;i>=1;i--)id[a[i]]=i; for(int i=1;i<=n;i++) { if(num[a[i]]==k) { ans[id[a[i]]]=i; id[a[i]]=Next[id[a[i]]]; } else num[a[i]]++; } // for(int i=1;i<=n;i++) // printf("%d ",ans[i]); // puts(""); build(1,n,1); // printf("%d ",2-1+1-query(1,2,1,n,1)); int q,last=0; scanf("%d",&q); while(q--) { int l,r; scanf("%d%d",&l,&r); l=(l+last)%n+1,r=(r+last)%n+1; if(l>r)swap(l,r); last=r-l+1-query(l,r,1,n,1); printf("%d ",last); } return 0; } /******************** ********************/