Subject link: https://codeforces.com/contest/813/problem/E
Main idea:
Given a sequence with a length of N, Q times inquiries are performed, and it is forced to be online within
each inquiry [l,r] (cnt represents the number of occurrences of i):
∑ min (cnti, k) \sum{min(cnt_i,k) }∑m i n ( c n ti,k)
Topic idea
This question is similar
to the number of different numbers in the interval. It can be implemented with a chairperson tree or a tree-like array.
Consider the implementation method of that question: 记录某个数上一次出现的位置
So the same, this question is similar to that question, just need: 记录某个数前面第k次出现的位置
This ensures that the number of occurrences is not It may be more than k. It’s
good to use the chairman tree to maintain it.
Code:
/*** keep hungry and calm CoolGuang! ***/
#pragma GCC optimize("Ofast","unroll-loops","omit-frame-pointer","inline")
#pragma GCC optimize(3)
#include <bits/stdc++.h>
#include<stdio.h>
#include<queue>
#include<algorithm>
#include<string.h>
#include<iostream>
#define debug(x) cout<<#x<<":"<<x<<endl;
#define d(x) printf("%lld\n",x);
typedef long long ll;
typedef unsigned long long ull;
using namespace std;
const ll INF= 1e17;
const ll maxn = 3e5+700;
const int mod= 1e9+7;
const int up = 1e9;
template<typename T>inline void read(T &a){
char c=getchar();T x=0,f=1;while(!isdigit(c)){
if(c=='-')f=-1;c=getchar();}
while(isdigit(c)){
x=(x<<1)+(x<<3)+c-'0';c=getchar();}a=f*x;}
ll n,m,p;
vector<int>b[maxn];
int pos[maxn];
struct node{
int l,r;
int w;
}t[maxn*30];
int root[maxn*30];
int cnt = 0;
void Insert(int &now,int pre,int l,int r,int pos,int w){
t[now = ++cnt] = t[pre];
t[now].w += w;
if(l == r) return ;
int mid = (l+r)/2;
if(pos <= mid) Insert(t[now].l,t[pre].l,l,mid,pos,w);
else Insert(t[now].r,t[pre].r,mid+1,r,pos,w);
}
ll Find(int now,int l,int r,int pos){
if(l == r) return t[now].w;
int mid = (l+r)/2;
if(pos <= mid) return Find(t[now].l,l,mid,pos) + t[t[now].r].w;
return Find(t[now].r,mid+1,r,pos);
}
int main(){
read(n);read(m);
for(int i=1;i<=n;i++){
int x;read(x);
Insert(root[i],root[i-1],1,n,i,1);
b[x].push_back(i);
if(b[x].size()>m){
Insert(root[i],root[i],1,n,b[x][pos[x]],-1);
pos[x]++;
}
}
read(p);
int last = 0;
for(int i=1;i<=p;i++){
int l,r;read(l);read(r);
l = (last+l)%n+1,r = (last+r)%n+1;
if(l>r) swap(l,r);
last = Find(root[r],1,n,l);
printf("%d\n",last);
}
return 0;
}
/***
10
0101011101
****/