bzoj3160 万径人踪灭
来源:互联网 发布:mac 搜狗输入法切换 编辑:程序博客网 时间:2024/06/16 07:02
传送门
奇怪的FFT+manacher以及容斥(?)。
题目要求求出不连续的回文序列,首先要想到用所有回文序列减掉连续的回文序列,连续的显然可以用manacher求出来,于是题目转化为求出所有的回文序列。巨大的脑洞:由于题目所给的字符串只包含a和b两种字符,所以我们将a看成1,b看成0做一遍FFT,然后将b看成1,a看成0再做一遍,就可以求出所有的对称字符对的对称中心下标乘2包含的对称字符对(大概理解一下)。这中间有个问题:对称中心有可能在字符上,也有可能在两个字符之间。这在FFT的作用下导致了一个问题:对于两个下标不同的字符对,它们会对其对称中心下标乘2的位置带来2的贡献;而对于同一个字符,它会给自己带来1的贡献。对于这个问题的处理,网上大多数的题解都是将贡献除以2然后上取整,于是导致我懵逼了一天,最后在zyz神犇的引导下解开了谜团;谜团的本质在之前已经说了,就不再详细赘述做法了。其余见代码。
CODE:
#include<cmath>#include<cstdio>#include<cstring>#include<complex>#include<iostream>using namespace std;#define mod 1000000007lltypedef long long ll;typedef complex<double> cp;const double pi=acos(-1);const int N=3e5+10;cp a[N],b[N];char s[N];int r[N],Ans[N],p[N],power[N];int len,n,m,Len;ll ans;inline int getstring(){ char c=getchar();int len=0; while(c!='a'&&c!='b') c=getchar(); while(c=='a'||c=='b') s[++len]=c,c=getchar(); return len;}inline void fft(cp *a,int f){ for(int i=0;i<n;i++) if(i<r[i]) swap(a[i],a[r[i]]); for(int i=1;i<n;i<<=1) { cp wn(cos(pi/i),f*sin(pi/i)); for(int j=0,tmp=i<<1;j<n;j+=tmp) { cp w(1,0); for(int k=0;k<i;k++,w*=wn) { cp x=a[j+k],y=w*a[j+k+i]; a[j+k]=x+y,a[j+k+i]=x-y; } } }}inline ll manacher(){ int mx=0,pos=0; ll ans=0; for(int i=len;i;i--) s[i<<1]=s[i],s[(i<<1)-1]='#'; len<<=1; s[len+1]=s[len+2]='#',s[0]='$'; for(int i=1;i<=len;i++) { if(mx>i) p[i]=min(p[pos*2-i],mx-i); else p[i]=1; while(s[i-p[i]]==s[i+p[i]]) p[i]++; if(i+p[i]>mx) mx=i+p[i],pos=i; ans+=1ll*p[i]>>1; } return ans;}int main(){ len=getstring();m=len<<1; for(n=1;n<m;n<<=1) Len++; for(int i=0;i<n;i++) r[i]=(r[i>>1]>>1)|((i&1)<<(Len-1)); for(int i=1;i<=len;i++) if(s[i]=='a') a[i-1]=1; else b[i-1]=1; fft(a,1),fft(b,1); for(int i=0;i<n;i++) a[i]*=a[i],b[i]*=b[i]; fft(a,-1),fft(b,-1); power[0]=1; for(int i=1;i<=m;i++) { power[i]=power[i-1]<<1; if(power[i]>=mod) power[i]-=mod; } for(int i=0;i<m;i++) { int tmp=(int)(a[i].real()/n+0.5)+(int)(b[i].real()/n+0.5)+1; ans+=power[tmp>>1]-1; if(ans>=mod) ans-=mod; } /*和上一个for的本质相同 for(int i=0;i<m;i++) { if(i&1) { int tmp=(int)(a[i].real()/n+0.5)+(int)(b[i].real()/n+0.5); ans+=power[tmp>>1]-1; } else { int tmp=(int)(a[i].real()/n+0.5)+(int)(b[i].real()/n+0.5); ans+=power[(tmp>>1)+1]-1; } if(ans>=mod) ans-=mod; } */ printf("%lld",((ans-manacher())%mod+mod)%mod); return 0;}
阅读全文
0 0
- bzoj3160: 万径人踪灭
- bzoj3160 万径人踪灭
- [bzoj3160]万径人踪灭
- BZOJ3160 万径人踪灭
- bzoj3160 万径人踪灭
- bzoj3160 万径人踪灭
- BZOJ3160: 万径人踪灭
- bzoj3160 万径人踪灭
- bzoj3160 万径人踪灭(FFT+manacher)
- bzoj3160 万径人踪灭 FFT+manacher
- 【bzoj3160】万径人踪灭 FFT+manacher
- BZOJ3160 万径人踪灭 FFT+manacher
- 【BZOJ3160】万径人踪灭 FFT manacher
- BZOJ3160: 万径人踪灭 FFT+manacher
- [bzoj3160][FFT][manacher]万径人踪灭
- [BZOJ3160]万径人踪灭 FFT+manacher
- bzoj3160
- [BZOJ3160]万径人踪灭(FFT+manacher)
- 秋招来袭
- unity服务器Photon Server学习笔记
- laravel 5.2队列延时
- 一个有趣的心理测试
- 如何在页面引用外部的HTML?
- bzoj3160 万径人踪灭
- ActiveMQ消息队列之java消息生产与消费
- 2017年年中总结——爱在继续……
- JS中隐藏的坑
- QML之TabView
- HDU-1525-Euclid's Game
- ubuntu16.04 nvidia显卡驱动安装
- Machine Learning---3--朴素贝叶斯
- Yii2 02-关于安装Advanced