【BZOJ3160】 万径人踪灭(FFT,manacher)
前言
多项式真的很难♂啊qwq
Solution
考虑求的是一个有间隔的回文串,相当于是:
总的答案-没有间隔的答案
考虑总的答案怎么计算?FFT卷一下就好了。
对于每一位字符,有两种取值,然后随便卷起来,卷起来就是当前这一位之前与它相同的字符个数(这一位不能是‘0’,也就是被排斥的那一位)
然后就可以轻松解决?
是的。
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
#include<iostream>
#include<queue>
#include<algorithm>
#include<complex>
#define ll long long
#define re register
using namespace std;
inline int gi(){int f=1,sum=0;char ch=getchar();while(ch>'9' || ch<'0'){if(ch=='-')f=-1;ch=getchar();}while(ch>='0' && ch<='9'){sum=(sum<<3)+(sum<<1)+ch-'0';ch=getchar();}return f*sum;
}
const int maxn=2000010,Mod=1e9+7;
const double Pi=acos(-1.0);
char s[maxn];
int len,N,M,p[maxn],r[maxn];
ll f[maxn],tw[maxn],ans;
complex<double>a[maxn],b[maxn];
ll manacher(){s[len+len+1]='#';s[0]=' ';for(int i=len;i;i--){s[i*2]=s[i];s[i*2-1]='#';}int mx=0,id=0;for(int i=1;i<=len+len;i++){p[i]=mx>i?min(p[id*2-i],mx-i):1;while(s[p[i]+i]==s[i-p[i]])p[i]++;if(i+p[i]>mx){id=i;mx=i+p[i];}}ll ret=0;for(int i=1;i<=len+len;i++)ret=(ret+p[i]/2)%Mod;return ret;
}
void FFT(complex<double> *P,int opt)
{for(int i=0;i<N;++i)if(i<r[i])swap(P[i],P[r[i]]);for(int i=1;i<N;i<<=1){complex<double> W(cos(Pi/i),opt*sin(Pi/i));for(int p=i<<1,j=0;j<N;j+=p){complex<double> w(1,0);for(int k=0;k<i;++k,w*=W){complex<double> X=P[j+k],Y=P[i+j+k]*w;;P[j+k]=X+Y;P[i+j+k]=X-Y;}}}
}
void work(char cc)
{memset(a,0,sizeof(a));memset(b,0,sizeof(b));for(int i=1;i<=len;++i)a[i]=b[i]=s[i]==cc;FFT(a,1);FFT(b,1);for(int i=0;i<N;++i)a[i]*=b[i];FFT(a,-1);for(int i=1;i<N;++i)a[i].real()=a[i].real()/N+0.5;for(int i=0;i<=M;++i)f[i]+=((int)(a[i].real())+1)/2;
}
int main(){scanf("%s",s+1);len=strlen(s+1);M=len+len;tw[0]=1;for(int i=1;i<=M;i++)tw[i]=(tw[i-1]+tw[i-1])%Mod;int l=0;for(N=1;N<=M;N<<=1)l++;for(int i=0;i<N;i++)r[i]=(r[i>>1]>>1)|((i&1)<<(l-1));work('a');work('b');for(int i=1;i<=M;i++)ans=(ans+tw[f[i]]-1)%Mod;printf("%lld\n",(ans-manacher()+Mod)%Mod);return 0;
}
转载于:https://www.cnblogs.com/mle-world/p/10278236.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部分挺裸的) ...
- 【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=回文子序列数- ...
最新文章
- openstack的网络、子网、端口的关系
- OpenJudge计算概论-找和为K的两个元素
- 《你的误区》《少有人走过的路》下载doc格式
- jpg , png 图片转SVG格式(资源篇)
- 水题 CodeForces 602C -Two Bases
- 查看数据库文件大小写
- Go语言中的结构体 (struct)
- [原]Greenplum failed segment的恢复方法
- hp服务器系统如何用u盘恢复,软硬件技巧 篇三:HP战66之恢复U盘制作,以及恢复系统之体验感想...
- 手把手教,使用Oracle VM VirtualBox虚拟机安装Windows XP系统,爷青回
- 【多传感器融合理论】01自动驾驶中常用传感器硬件介绍
- 辛弃疾 菩萨蛮·书江西造口壁
- 关系模式无损分解的测试方法
- 熊猫烧香被恶搞,网友爆笑诗词句大集合
- 论文阅读-Detecting and Recovering Sequential DeepFake Manipulation(SeqFakeFormer)
- java arraylist.add(),Java ArrayList add()方法与示例
- html 用户列表,用户列表.html
- Apache Airflow系列文章
- zipJS 前端压缩使用
- Numeric Keypad