bzoj 乱刷计划

# 题解

$a$$a$就是$1$$1$$b$$b$就是$2$$2$$c$$c$就是$3$$3$。。。$x$$x$就是${2}^{i}$$2^i$

CODE:

#include<cstdio>
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cmath>
using namespace std;
typedef long long LL;
const int N=60005;
{
int x = 0 , f = 1;
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 n,m;
char ss[N];
int p[N];
int size;
int belong[N];
int ha[N];//异或前缀和
unsigned short f[1<<26];
int R[N];
void Ins (int x,int o)
{
x=ha[x];
f[x]+=o;
for (int u=0; u<26; u++) f[x^p[u]]+=o;

}
struct qq
{
int l,r,id;
} q[N];
bool cmp (qq a,qq b)
{
return belong[a.l]==belong[b.l]?a.r<b.r:a.l<b.l;
}
LL Ans[N];
int Bl(int l,int r)
{
int ans2=0;
for(int i=l; i<=r; ++i)
Ins(i-1,1),ans2+=f[ha[i]];
for(int i=l; i<=r; ++i) Ins(i-1,-1);
return ans2;
}
LL ans,pre[N];
int main()
{
size=sqrt(26*n);
//size=1;
for (int u=1; u<=n; u++) belong[u]=(u-1)/size+1;
p[0]=1;
for (int u=1; u<26; u++) p[u]=p[u-1]<<1;
scanf("%s",ss+1);
int tot=(n-1)/size+1;
for (int u=1; u<=n; u++) ha[u]=ha[u-1]^p[ss[u]-'a'];
for (int u=1; u<=tot; u++)
{
R[u]=min(n,u*size);
ans=0;
for (int i=R[u]; i>R[u-1]; i--)
{
Ins(i,1),ans=ans+f[ha[i-1]],pre[i]=ans;
}
for (int i=R[u]; i>R[u-1]; i--)  Ins(i,-1);
}
sort(q+1,q+1+m,cmp);
int last=0;
int r=0;//右端点在哪里
for (int u=1; u<=m; u++)
{
if (belong[q[u].l]!=last)//扩过了这一块
{
for (int i=R[last]; i<r; i++) Ins(i,-1);
last=belong[q[u].l];
r=R[last];
ans=0;
}
if (belong[q[u].l]==belong[q[u].r]) Ans[q[u].id]=Bl(q[u].l,q[u].r);
else
{
while(r<q[u].r) ++r,Ins(r-1,1),ans+=f[ha[r]];
LL ans2=0;
Ins(r,1);
Ins(R[last],-1);
for(int j=q[u].l; j<=R[last]; ++j) ans2+=f[ha[j-1]];
Ans[q[u].id]=ans+pre[q[u].l]+ans2;
Ins(r,-1);
Ins(R[last],1);
}
}
for (int u=1; u<=m; u++)
printf("%lld\n",Ans[u]);
return 0;
}

• 广告
• 抄袭
• 版权
• 政治
• 色情
• 无意义
• 其他

120