题意:给定数列,mm次询问 [ l i , r i ] [l_i,r_i] [li,ri]中,出现正偶数次的数的个数。
idea:之前我们是做过问区间众数的题的,这题跟那题比较类似,但不完全相同。我们需要预处理出 c n t [ i ] [ j ] cnt[i][j] cnt[i][j] 为前 i i i块中 j j j出现的次数, a n s [ i ] [ j ] ans[i][j] ans[i][j]为第 i i i块到第 j j j块中出现偶数次的数的个数
ACcode:
#include<iostream>
#include<cstring>
#include<cstdio>
#define LL long long
#include<cmath>
#define N 100010
#define SQ 1010
using namespace std;
int n,m,c,cnt[SQ][N],ans[SQ][SQ],val[N],bl[N],st[SQ],ed[SQ],maxx=-1,t[N],sq;
void init()
{
for(int i=1;i<=bl[n];i++)
{
st[i] = (i-1)*sq + 1;
ed[i] = i*sq ;
}
ed[ bl[n] ] = n;
for(int i=1;i<=bl[n];i++)
{
for(int j=0;j<=c;j++)
{
cnt[i][j] += cnt[i-1][j];
}
}
for(int i=1;i<=bl[n];i++)
{
for(int j=i;j<=bl[n];j++)
{
ans[i][j] = ans[i][j-1];
for(int k=st[j];k<=ed[j];k++)
{
t[ val[k] ]++;
if( t[ val[k] ]%2==0 ) ans[i][j]++;
else if( t[ val[k] ]>=3 ) ans[i][j]--;
}
}
memset(t,0,sizeof(t));
}
}
int query(int l,int r)
{
int sum = 0;
if( bl[l]+1>=bl[r] )//特别注意,这题当[l,r]都相邻两个块或者同一个块是要直接加不然会出问题
{
for(int i=l;i<=r;i++)
{
t[ val[i] ]++;
if( t[ val[i] ]%2==0 ) sum++;//说明在t[]在+1之前是奇数,所以这是一种新方案
else if( t[ val[i] ]>=3 ) sum--; //说明t[]在+1之前是偶数,并且之前的t[]>=2故sum需-1
}
for(int i=l;i<=r;i++) t[ val[i] ]--;
return sum;
}
sum = ans[ bl[l]+1 ][ bl[r]-1 ];
for(int i=l;i<=min( r,ed[ bl[l] ] );i++)
{
t[ val[i] ]++;
int v = cnt[ bl[r]-1 ][ val[i] ] - cnt[ bl[l] ][ val[i] ];
if( (t[ val[i] ]+v)%2==0 ) sum++;
else if( (t[ val[i] ]+v)>=3 ) sum--;
}
if( bl[l] != bl[r] )
{
for(int i=st[ bl[r] ];i<=r;i++)
{
t[ val[i] ]++;
int v = cnt[ bl[r]-1 ][ val[i] ] - cnt[ bl[l] ][ val[i] ];
if( (t[ val[i] ]+v)%2==0 ) sum++;
else if( t[ val[i] ]+v >=3 ) sum--;
}
for(int i=st[ bl[r] ];i<=r;i++) t[ val[i] ]--;
}
for(int i=l;i<=min( r,ed[bl[l]] );i++) t[ val[i] ]--;
return sum;
}
void solve()
{
scanf("%d %d %d",&n,&c,&m);
sq = sqrt(n);
for(int i=1;i<=n;i++)
{
scanf("%d",&val[i]);
bl[i] = (i-1)/sq + 1;
cnt[ bl[i] ][ val[i] ]++;
}
init();
int as = 0;
while( m-- )
{
int l,r;
scanf("%d %d",&l,&r);
l = (l+as) % n + 1;
r = (r+as) % n + 1;
if( l>r ) swap( l,r );
as = query( l,r );
printf("%d\n",as);
}
}
signed main()
{
//freopen("in.txt","r",stdin);
solve();
return 0;
}