bzoj2821 作诗(Poetize)分块+二分
预处理的d[i][j]为第i块到第j点的答案
块外的暴力
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<cmath>
using namespace std;
#define maxn 100100
#define maxs 320
int S,T;
int n,m,c;
vector<int> col[maxn];
int a[maxn];
int le[maxs],ri[maxs];
int d[maxs][maxn];
int rec,cas;
int op[maxs],cc[maxn];
int lab[maxn],num;
int ask(int x,int y){
    int mid,l=-1,r=col[y].size();
    while(l+1!=r){
	   mid=(l+r)>>1;
	   	if(col[y][mid]>x)r=mid;
	   	else l=mid;
	}
	return r;
}
inline int sum(int x,int y,int z){
    return ask(y,z)-ask(x-1,z);	
}
int in[maxn];
inline void put(int x){
    if(lab[a[x]]!=cas){
		op[++num]=a[x];
		lab[a[x]]=cas;
		cc[a[x]]=0;
	}	
	cc[a[x]]++;
}
int query(int x,int y){
	int ans=0,ss;
	int l=in[x]+1;
    num=0;
    if(in[x]==in[y])for(int i=x;i<=y;i++)put(i);
	else for(int i=x;i<=ri[in[x]];i++)put(i);
	if(in[x]!=in[y]){
		ans=d[l][y];
		for(int i=1;i<=num;i++){
			ss=sum(le[l],y,op[i]);
		   if(cc[op[i]]&1){
		      if(ss&1)ans++;
			  else if(ss)ans--;		
		   }else{
				if(ss&1);
				else if(!ss)ans++;
			}	
		}
	}else for(int i=1;i<=num;i++)if(!(cc[op[i]]&1))ans++;		
	return ans;
}
int main(){
	scanf("%d%d%d",&n,&c,&m);
	for(int i=1;i<=n;i++){
	  scanf("%d",&a[i]);
	  col[a[i]].push_back(i);	
	}
    T=sqrt(n);
    if(n-T*T>(T+1)*(T+1)-n)T++;
	int now=0;
	for(int i=1;i<=n;i++,now--){
		if(!now)S++,now=T,le[S]=i,ri[S-1]=i-1;
	    in[i]=S;	
	}
	ri[S]=n;
	for(int i=1;i<=S;i++){
		memset(cc,0,sizeof(cc));
		rec=0;
		for(int j=le[i];j<=n;j++){
		    if(cc[a[j]]){if(cc[a[j]]&1)rec++;else rec--;}
			cc[a[j]]++;
			d[i][j]=rec;
		}	
	}
	int lans=0;
	for(cas=1;cas<=m;cas++){
		int x,y;
		scanf("%d%d",&x,&y);
		x=(x+lans)%n+1;
		y=(y+lans)%n+1;
		if(x>y)swap(x,y);
		lans=query(x,y);
		printf("%d\n",lans);
	}
}
 
                    
                     
                    
                 
                    
                
 
 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号