Luogu P4199 万径人踪灭

题链1
题链2

分析

条件2可以用容斥,Manacher
接下来只需求对于每个对称轴\(i\),有多少种点对选取方式满足关于\(i\)对称
不妨设\(f[i]\)表示以\(\frac{i}{2}\)为对称轴的对称点对数

\[ f[i]=\sum_{j+k=i}[s[j]==s[k]] \]

像极了FFT,考虑FFT
又只有两个字母仿佛在暗示我们什么
可以设\(b[i]\)表示\(s[i]=='a'\),\(b'[i]\)表示\(s[i]=='b'\)

\[ f[i]=\sum_{j+k=i} b[j]*b[k]+b'[j]*b'[k] \]

FFT优化
PS:注意FFT的精度问题

#include<bits/stdc++.h>
#define ll long long
#define db double
const int p=1e9+7;
double Pi=acos(-1);
using namespace std;

inline int mo(int x) {
	return x>=p?x-p:x;
}
inline int ksm(ll a,int b) {
	ll ret=1;
	while(b) {
		if(b&1) ret=ret*a%p;
		a=a*a%p,b>>=1;
	}
	return ret;
}

const int N=4e5+5;
int ans,rev[N],L,n,m,len,R[N],f[N];
char s[N],a[N];

struct cp {double a,b; }b[N];
cp operator +(cp x,cp y) {
	return (cp){x.a+y.a,x.b+y.b};
}
cp operator -(cp x,cp y) {
	return (cp){x.a-y.a,x.b-y.b};
}
cp operator *(cp x,cp y) {
	return (cp){x.a*y.a-x.b*y.b,x.a*y.b+x.b*y.a};
}
void fft(cp *a,int op) {
	for(int i=0;i<len;i++) {
		if(i>rev[i]) swap(a[i],a[rev[i]]);
	}
	for(int i=1;i<len;i<<=1) {
		cp Wn=(cp){cos(Pi/i),sin(Pi/i)*op};
		for(int j=0;j<len;j+=(i<<1)) {
			cp w=(cp){1,0};
			for(int k=j;k<j+i;k++) {
				cp t=w*a[k+i];
				a[k+i]=a[k]-t;
				a[k]=a[k]+t;
				w=w*Wn;
			}
		}
	}
}
int main() {
	scanf("%s",s+1),n=strlen(s+1); 
	L=0; len=1;
	while(len<n+n-1) len<<=1,L++;
	for(int i=1;i<=len;i++) {
		rev[i]=(rev[i>>1]>>1)|((i&1)<<(L-1));
	}
	for(int i=0;i<n;i++) {
		b[i].a=(s[i+1]=='a');
	}
	fft(b,1);
	for(int i=0;i<len;i++) b[i]=b[i]*b[i];
	fft(b,-1); 
	for(int i=0;i<len;i++) {
		f[i]=(int)((b[i].a+0.5)/len);
	}
	for(int i=0;i<len;i++) {
		b[i]=(cp){(db)(s[i+1]=='b'),0};
	}
	fft(b,1);
	for(int i=0;i<len;i++) b[i]=b[i]*b[i];
	fft(b,-1);
	for(int i=0;i<len;i++) {
		f[i]+=(int)((b[i].a+0.5)/len);
		ans=mo(ans+ksm(2,f[i]+1>>1)-1);
	}
	a[0]='*',a[m=1]='|';
	for(int i=1;i<=n;i++) {
		a[++m]=s[i],a[++m]='|';
	}
	for(int i=1,r=0,mid=0;i<=m;i++){
		if(i<=r) R[i]=min(R[(mid<<1)-i],r-i+1);
		while(a[i+R[i]]==a[i-R[i]]) R[i]++;
		if(i+R[i]>r) {
			mid=i,r=i+R[i]-1;
		}
		ans=mo(ans-(R[i]>>1)+p);
	}
	printf("%d\n",ans);
	return 0;
}
posted @ 2021-03-01 09:06  wwwsfff  阅读(58)  评论(0)    收藏  举报