真的是。。。异或前缀和没想到啊。。。
#include<cstdio> #include<iostream> #include<cstring> #include<cstdlib> #include<algorithm> #include<cmath> using namespace std; int read() { int f=1,x=0;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f; } int Bin[35]; int n,s[61000],lslen,ls[61000]; char ss[35]; int g[61000][30]; int m; struct query{int l,r,id;}q[61000];int st[61000],block,as[61000]; bool cmp(query n1,query n2){return st[n1.l]==st[n2.l]?n1.r<n2.r:st[n1.l]<st[n2.l];} //----------------------init--------------------------------------- int v[61000],ans,l,r; void add_l(int p) { ans+=v[s[p-1]]+(s[r]==s[p-1]); for(int j=1;j<=26;j++) if(g[p-1][j]!=-1)ans+=v[g[p-1][j]]+(s[r]==g[p-1][j]); v[s[p-1]]++; } void add_r(int p) { v[s[p-1]]++;ans+=v[s[p]]; for(int j=1;j<=26;j++) if(g[p][j]!=-1)ans+=v[g[p][j]]; } void del_l(int p) { v[s[p-1]]--;ans-=v[s[p-1]]+(s[r]==s[p-1]); for(int j=1;j<=26;j++) if(g[p-1][j]!=-1)ans-=v[g[p-1][j]]+(s[r]==g[p-1][j]); } void del_r(int p) { ans-=v[s[p]]; for(int j=1;j<=26;j++) if(g[p][j]!=-1)ans-=v[g[p][j]]; v[s[p-1]]--; } void solve() { l=1,r=0;ans=0; memset(v,0,sizeof(v)); for(int i=1;i<=m;i++) { while(q[i].l<l)l--, add_l(l); while(r<q[i].r)r++, add_r(r); while(l<q[i].l)del_l(l), l++; while(q[i].r<r)del_r(r), r--; as[q[i].id]=ans; } } //------------------------莫队---------------------------------- int erfen(int d) { int l=1,r=lslen; while(l<=r) { int mid=(l+r)/2; if(ls[mid]==d)return mid; if(ls[mid]<d)l=mid+1; else r=mid-1; } return -1; } int main() { freopen("a.in","r",stdin); freopen("a.out","w",stdout); Bin[1]=1;for(int i=2;i<=27;i++)Bin[i]=Bin[i-1]*2; n=read();m=read(); scanf("%s",ss+1); lslen=0; s[0]=0; ls[++lslen]=s[0]; for(int i=1;i<=n;i++) { int x=ss[i]-'a'+1; s[i]=s[i-1]^Bin[x]; ls[++lslen]=s[i]; } sort(ls+1,ls+lslen+1); lslen=unique(ls+1,ls+lslen+1)-ls-1; for(int i=0;i<=n;i++) { g[i][0]=lower_bound(ls+1,ls+lslen+1,s[i])-ls; for(int j=1;j<=26;j++) g[i][j]=erfen(s[i]^Bin[j]); s[i]=g[i][0]; } block=int(sqrt(double(n+1))); for(int i=1;i<=n;i++)st[i]=(i-1)/block+1; for(int i=1;i<=m;i++) q[i].l=read(), q[i].r=read(), q[i].id=i; sort(q+1,q+m+1,cmp); solve(); for(int i=1;i<=m;i++)printf("%d ",as[i]); return 0; }