BZOJ3160:万径人踪灭(FFT,Manacher)
Solution
$ans=$回文子序列$-$回文子串的数目。
后者可以用$manacher$直接求。
前者设$f[i]$表示以$i$为中心的对称的字母对数。
那么回文子序列的数量也就是$\sum_{i=0}^{n-1}2^{f[i]-1}$
构造两个数组$a[i],b[i]$。若第$i$位为$a$,那么$a[i]=1$,否则$b[i]=1$。
可以发现$a$数组自身卷积就是$a$字母对$f$数组的贡献,$b$数组同理。
卷下$a$,卷下$b$,对应位置求和,就是$f$数组。
因为在卷积中每对对称字符被算了两次,而自己和自己关于自己对称只算了一次,所以要把答案除2向上取整。
Code
1 #include<iostream> 2 #include<cstring> 3 #include<cstdio> 4 #include<cmath> 5 #define N (400009) 6 #define LL long long 7 #define MOD (1000000007) 8 using namespace std; 9 10 int n,fn,l,tot,r[N],len[N],p[N]; 11 LL Re,fun; 12 char s[N],st[N]; 13 double pi=acos(-1.0); 14 struct complex 15 { 16 double x,y; 17 complex (double xx=0,double yy=0) 18 { 19 x=xx; y=yy; 20 } 21 }a[N],b[N]; 22 23 complex operator + (complex a,complex b) {return complex(a.x+b.x,a.y+b.y);} 24 complex operator - (complex a,complex b) {return complex(a.x-b.x,a.y-b.y);} 25 complex operator * (complex a,complex b) {return complex(a.x*b.x-a.y*b.y,a.x*b.y+a.y*b.x);} 26 complex operator / (complex a,double b) {return complex(a.x/b,a.y/b);} 27 28 void FFT(int n,complex *a,int opt) 29 { 30 for (int i=0; i<n; ++i) 31 if (i<r[i]) swap(a[i],a[r[i]]); 32 for (int k=1; k<n; k<<=1) 33 { 34 complex wn=complex(cos(pi/k),opt*sin(pi/k)); 35 for (int i=0; i<n; i+=k<<1) 36 { 37 complex w=complex(1,0); 38 for (int j=0; j<k; ++j,w=w*wn) 39 { 40 complex x=a[i+j], y=w*a[i+j+k]; 41 a[i+j]=x+y; a[i+j+k]=x-y; 42 } 43 } 44 } 45 if (opt==-1) for (int i=0; i<n; ++i) a[i]=a[i]/n; 46 } 47 48 void Manacher() 49 { 50 s[++tot]='('; s[++tot]='#'; 51 for (int i=0; i<n; ++i) 52 s[++tot]=st[i], s[++tot]='#'; 53 s[++tot]=')'; 54 int maxn=0,mid=0,x; 55 for (int i=1; i<=tot; ++i) 56 { 57 if (i>maxn) x=1; 58 else x=min(maxn-i+1,len[mid*2-i]); 59 while (s[i+x]==s[i-x]) x++; 60 len[i]=x; 61 if (i+x-1>maxn) maxn=i+x-1, mid=i; 62 fun=(fun+len[i]/2)%MOD; 63 } 64 } 65 66 int main() 67 { 68 p[0]=1; 69 for (int i=1; i<=100000; ++i) 70 p[i]=p[i-1]*2%MOD; 71 scanf("%s",st); n=strlen(st); 72 Manacher(); 73 74 fn=1; 75 while (fn<=n+n) fn<<=1, l++; 76 for (int i=0; i<fn; ++i) 77 r[i]=(r[i>>1]>>1) | ((i&1)<<(l-1)); 78 for (int i=0; i<n; ++i) 79 if (st[i]=='a') a[i].x=1; 80 else b[i].x=1; 81 FFT(fn,a,1); FFT(fn,b,1); 82 for (int i=0; i<fn; ++i) 83 a[i]=a[i]*a[i], b[i]=b[i]*b[i]; 84 FFT(fn,a,-1); FFT(fn,b,-1); 85 for (int i=0; i<fn; ++i) 86 { 87 int x=(a[i].x+b[i].x+0.5); 88 x=(x+1)>>1; 89 Re=(Re+p[x]-1)%MOD; 90 } 91 printf("%lld\n",(Re-fun+MOD)%MOD); 92 }
转载于:https://www.cnblogs.com/refun/p/10091484.html
BZOJ3160:万径人踪灭(FFT,Manacher)相关推荐
- 洛谷P4199 万径人踪灭(manacher+FFT)
传送门 题目所求为所有的不连续回文子序列个数,可以转化为回文子序列数-回文子串数 回文子串manacher跑一跑就行了,考虑怎么求回文子序列数 我们考虑,如果$S_i$是回文子序列的对称中心,那么只要 ...
- BZOJ 3160 FFT+Manacher
思路: 这道题思路好奇怪--. 我们先要知道关于x (x可以是间隙) 对称的有几对字母 显然暴力是n^2的 那怎么办呢 先把所有'a'看成1 'b'看成0 意外的发现 这不就是卷积嘛 再倒过来搞一搞 ...
- BZOJ3160:万径人踪灭
Description Input & Output & Sample Input & Sample Output HINT 题解: 题意即求不连续但间隔长度对称的回文串个数. ...
- BZOJ3160: 万径人踪灭
设a[i]=bool(s[i]=='a'),b[i]=bool(s[i]=='b'),考虑a和a.b和b的卷积,由于卷积是对称的,就可以统计出不连续回文子串个数了.可能说得比较简略.再用manache ...
- manacher算法学习(求最长回文子串长度)
Manacher总结 我的代码 学习:yyb luogu题目模板 xzy的模板 #include<iostream> #include<cstdlib> #include< ...
- 【BZOJ3160】万径人踪灭 Manacher+FFT
[BZOJ3160]万径人踪灭 Description Input Output Sample Input Sample Output HINT 题解:自己想出来1A,先撒花~(其实FFT部分挺裸的) ...
- 【BZOJ3160】 万径人踪灭(FFT,manacher)
前言 多项式真的很难♂啊qwq Solution 考虑求的是一个有间隔的回文串,相当于是: 总的答案-没有间隔的答案 考虑总的答案怎么计算?FFT卷一下就好了. 对于每一位字符,有两种取值,然后随便卷 ...
- 【BZOJ 3160】 3160: 万径人踪灭 (FFT)
3160: 万径人踪灭 Time Limit: 10 Sec Memory Limit: 256 MB Submit: 1440 Solved: 799 Description Input Out ...
- 【bzoj3160】万径人踪灭
题意:给一个只含a.b的字符串,求所有的回文不连续子序列. manacher+FFT. 先求出所有回文序列,再减去连续子序列(即回文串). 将a.b分开考虑,对于一个对称轴,以其为回文中心的回文序列的 ...
- bzoj3160(FFT+回文自动机)
题目描述 https://www.lydsy.com/JudgeOnline/problem.php?id=3160 题解 先把问题转化一下,我们要求的是非连续对称回文子序列. ans=回文子序列数- ...
最新文章
- return error怎么定义_SpringBoot 系列 web 篇之自定义返回 Http Code 的 n 种姿势
- ios3怎么取消长按弹出菜单_苹果:iOS13取消3D-Touch重压改为长按只是个BUG~
- 王道408数据结构——第二章 线性表
- PHP通知弹窗代码_公告弹窗
- 深度学习《Photo Editing》
- ffmpeg前景_5G时代音视频开发前景怎么样?音视频开发需要掌握哪些技术?
- 利用Windows的启动机制实现拦截360的运行
- HashPasswordForStoringInConfigFile 已过时
- pandownload搜索引擎脚本
- ubuntu字体丑_科学网—关于ubuntu系统的一点经验——字体崩溃 - 苗玉虎的博文
- Android 混淆配置
- [Loj 6070][回文树+可持久化线段树+border理论]基因
- UFS系列三:UFS数据包UPIU
- java 开发脚本视频_你写脚本,AI自动剪视频:13分钟完成剪辑师7小时创作
- Shell脚本循环语句及exit、continue和break用法
- 2021-7-14-超融合基础知识
- python神经网络算法pdf_高清图解:神经网络、机器学习、数据科学一网打尽|附PDF...
- 阿里一日游,入职当天即提辞职
- dom4j 获取xml中指定节点的信息
- python情感分析:基于jieba的分词及snownlp的情感分析!