Loading

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();
	}
}

posted @ 2022-08-25 21:09  Into_qwq  阅读(30)  评论(0编辑  收藏  举报