P7114 [NOIP2020] 字符串匹配 思路简记
https://www.luogu.com.cn/blog/nitubenben/solution-p7114#
这篇题解写的很详细啊
那我就不写了
#include<bits/stdc++.h>
using namespace std;
const int N=(1<<20)+5;
#define ll long long
#define lowbit(x) x&-x
#define rst(f) memset(f,0,sizeof(f))
char s[N];
int n,tot,pre,suc;
int z[N],c[28],be[N],af[N];
inline void add(int x){
for(;x<=27;x+=lowbit(x))
++c[x];
}
inline int query(int x){
int res=0;
for(;x;x-=lowbit(x))
res+=c[x];
return res;
}
inline void Z(){
z[0]=n;
int a=0,p=0;
for(int i=1;i<n;++i){
if(i>=p||i+z[i-a]>=p){
if(i>=p)
p=i;
while(p<n&&s[p]==s[p-i])
++p;
z[i]=p-i;
a=i;
}
else
z[i]=z[i-a];
}
}
inline void solve(){
scanf("%s",s);
n=strlen(s);
rst(be),rst(af),rst(c);
Z();
int tot=0,pre=0,suc=0;
ll ans=0;
for(int i=0;i<n;++i){
if(z[i]+i==n) --z[i];
++af[s[i]-'a'];
}
for(int i=0;i<26;++i)
if(af[i]&1) ++tot;
suc=tot;
for(int i=0;i<n;++i){
suc+=(af[s[i]-'a']&1)?-1:1;
--af[s[i]-'a'];
pre+=(be[s[i]-'a']&1)?-1:1;
++be[s[i]-'a'];
if(i!=0&&i!=n-1){
int t=z[i+1]/(i+1)+1;
ans+=1ll*(t/2)*query(tot+1)+1ll*(t-t/2)*query(suc+1);
}
add(pre+1);
}
cout<<ans<<endl;
}
signed main(){
int T;
cin>>T;
while(T--){
solve();
}
}