进阶指南上面的题目都十分经典,但是经典题难度一点都不低,特别是对于我这种还没入门的萌新来说╥﹏╥...题目的意思是求一段[l,r]之内数量为偶数的数字的总数量,这道题的标注是分块,但是我分块的经验几乎为零,无法,只能去找题解了。搜寻过程中发现了神犇hzwer的博客,实在是宝藏http://hzwer.com/,通过大佬的代码,大概写一下自己的理解吧...
#include<iostream> #include<cstdio> #include<cstdlib> #include<algorithm> #include<cstring> #include<cmath> #define inf 0x7fffffff using namespace std; inline int read() { int x=0,f=1;char ch=getchar(); while(ch>'9'||ch<'0'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f; } int n,c,m,block,cnt; int L[1505],R[1505],f[1505][1505]; int a[100005],belong[100005],tmp[100005],first[100005],last[100005]; int lastans; bool mark[100005]; struct data{int p,v;}b[100005]; inline bool operator<(data a,data b) { return (a.v<b.v)||(a.v==b.v&&a.p<b.p); } void pre() { int tot; for(int i=1;i<=cnt;i++) { for(int j=L[i];j<=n;j++)tmp[a[j]]=0; tot=0; for(int j=L[i];j<=n;j++) { if(!(tmp[a[j]]&1)&&tmp[a[j]])tot--; tmp[a[j]]++; if(!(tmp[a[j]]&1))tot++; f[i][belong[j]]=tot; } } for(int i=1;i<=n;i++) b[i].p=i,b[i].v=a[i]; sort(b+1,b+n+1); for(int i=1;i<=n;i++) { if(!first[b[i].v])first[b[i].v]=i; last[b[i].v]=i; } } int findup(int x,int v) { int l=first[v],r=last[v]; int tmp=0; while(l<=r) { int mid=(l+r)>>1; if(x<b[mid].p)r=mid-1; else {l=mid+1;tmp=mid;} } return tmp; } int finddown(int x,int v) { int l=first[v],r=last[v]; int tmp=inf; while(l<=r) { int mid=(l+r)>>1; if(x>b[mid].p)l=mid+1; else {tmp=mid;r=mid-1;} } return tmp; } int find(int x,int y,int v) { return max(findup(y,v)-finddown(x,v)+1,0); } int que(int x,int y) { int ans=0,t1,t2,a1,bx=belong[x],by=belong[y]; if(bx==by||bx+1==by) { for(int i=x;i<=y;i++) { a1=a[i];if(mark[a1])continue; int t=find(x,y,a1); if(!(t&1)){mark[a1]=1;ans++;} } for(int i=x;i<=y;i++)mark[a[i]]=0; } else { int l=L[bx+1],r=R[by-1]; ans=f[bx+1][by-1]; for(int i=x;i<l;i++) { a1=a[i];if(mark[a1])continue; t1=find(x,y,a1),t2=find(l,r,a1); if(!(t1&1)) {if((t2&1)||!t2)ans++;} else if(!(t2&1)&&t2)ans--; mark[a1]=1; } for(int i=r+1;i<=y;i++) { a1=a[i];if(mark[a1])continue; t1=find(x,y,a1),t2=find(l,r,a1); if(!(t1&1)) {if((t2&1)||!t2)ans++;} else if(!(t2&1)&&t2)ans--; mark[a1]=1; } for(int i=x;i<l;i++)mark[a[i]]=0; for(int i=r+1;i<=y;i++)mark[a[i]]=0; } return ans; } int main() { n=read();c=read();m=read(); for(int i=1;i<=n;i++)a[i]=read(); block=sqrt((double)n/log((double)n)*log(2)); if(n%block)cnt=n/block+1; else cnt=n/block; for(int i=1;i<=n;i++)belong[i]=(i-1)/block+1; for(int i=1;i<=cnt;i++) L[i]=(i-1)*block+1,R[i]=i*block; R[cnt]=n; pre(); for(int i=1;i<=m;i++) { int l=read(),r=read(); int x=(l+lastans)%n+1,y=(r+lastans)%n+1; if(x>y)swap(x,y); lastans=que(x,y); printf("%d\n",lastans); } return 0; }