BZOJ 3160: 万径人踪灭

题目传送门

【题目大意】

  给定一个长度为n的01串,求有多少个回文子序列?

  回文子序列是指从原串中找出任意个,使得构成一个回文串,并且位置也是沿某一对称轴对称。

  假如x是对称轴,若 i 和 j 是对称且di=dj,i,j可以视为可行的一组。可行组数记为f[x]。

  \(f[x]=\sum_{i=1}^{x-1}[d[x-i]==d[x+i]]\)

  以x为对称轴的答案是2^(f[x])-1。

  可以观察发现将d[i]=1的A[i]标为1,A与A做一次卷积,即可得出d[i]=1的f[]。(因为\(p^{x-i}*p^{x+i}=p^x\))

  对d[i]=1的做一次卷积,对d[i]=0的做一次卷积,加起来就是完整的f[]。

  由于单个连续一段的回文串不算,做一次manacher,减掉就行了。(ps:感觉这是强行加上去的条件,增加码量……)

  正解:FFT+快速幂+manacher

#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm> #define imax(a,b) ((a>b)?(a):(b))
#define imin(a,b) ((a<b)?(a):(b)) using namespace std; typedef long long ll; const ll mods=1000000007;
const int N=101000;
const double pi=acos(-1.0);
char st[N];
int n,d[N<<1],dn;
int nn,k,F[N<<1];
ll sum,tp[N<<2],power[N<<2];
struct Complex
{
double real,image;
Complex() {}
Complex(double _real,double _image)
{
real=_real; image=_image;
}
friend Complex operator + (Complex A,Complex B) { return Complex(A.real+B.real,A.image+B.image); }
friend Complex operator - (Complex A,Complex B) { return Complex(A.real-B.real,A.image-B.image); }
friend Complex operator * (Complex A,Complex B) { return Complex(A.real*B.real-A.image*B.image,A.image*B.real+A.real*B.image); }
} A[N<<2],B[N<<2];
int rev[N<<2]; void FFT(Complex *A,int n,int DFT)
{
for(int i=0;i<n;i++) if(i<rev[i]) swap(A[i],A[rev[i]]);
for(int s=1;(1<<s)<=n;s++)
{
int mi=(1<<s);
Complex wn=Complex(cos(2*pi/mi),DFT*sin(2*pi/mi));
for(int t=0;t<n;t+=mi)
{
Complex w=Complex(1,0);
for(int j=0;j<(mi>>1);j++)
{
Complex u=A[t+j],v=w*A[t+j+(mi>>1)];
A[t+j]=u+v; A[t+j+(mi>>1)]=u-v;
w=w*wn;
}
}
}
if(DFT==-1) for(int i=0;i<n;i++) A[i].real/=n,A[i].image/=n;
} ll manacher()
{
F[1]=0; int p=1; ll re=0ll;
for(int i=2;i<=dn;i++)
{
F[i]=imax(0,imin(F[2*p-i],F[p]+p-i));
while(d[i+F[i]+1]==d[i-F[i]-1]) F[i]++;
if(F[i]+i>F[p]+p) p=i;
re=(re+((F[i]+1)>>1))%mods;
}
return re;
} ll Pow(ll x,ll y)
{
ll s=1ll;
for(;y;y>>=1,x=x*x%mods) s=s*x%mods;
return s;
} int main()
{
scanf("%s",st); n=strlen(st);
dn=1; d[1]=4;
for(int i=1;i<=n;i++)
{
d[++dn]=3;
d[++dn]=st[i-1]-'a';
} d[++dn]=3; d[++dn]=5; sum=(mods-manacher())%mods; int m=n<<1; k=0;
for(nn=1;nn<=m;nn<<=1) k++;
for(int i=0;i<nn;i++) rev[i]=(rev[i>>1]>>1)|((i&1)<<(k-1)); power[0]=1ll;
for(int i=1;i<=nn;i++) power[i]=(power[i-1]<<1)%mods; for(int i=1;i<=n;i++) if(st[i-1]=='a') A[i].real=1;
FFT(A,nn,1); for(int i=0;i<=nn;i++) B[i]=A[i]*A[i]; memset(A,0,sizeof(A));
for(int i=1;i<=n;i++) if(st[i-1]=='b') A[i].real=1;
FFT(A,nn,1); for(int i=0;i<=nn;i++) B[i]=B[i]+A[i]*A[i]; FFT(B,nn,-1); for(int i=1;i<nn;i++) tp[i]=ll(B[i].real+0.5);
//for(int i=1;i<nn;i++) printf("%lld\n",tp[i]);
for(int i=1;i<nn;i++) (sum+=power[(tp[i]+1)>>1]-1)%=mods; printf("%lld\n",(sum%mods+mods)%mods);
return 0;
}

BZOJ 3160: 万径人踪灭 FFT+快速幂+manacher的更多相关文章

  1. BZOJ 3160: 万径人踪灭 [fft manacher]

    3160: 万径人踪灭 题意:求一个序列有多少不连续的回文子序列 一开始zz了直接用\(2^{r_i}-1\) 总-回文子串 后者用manacher处理 前者,考虑回文有两种对称形式(以元素/缝隙作为 ...

  2. bzoj 3160 万径人踪灭 FFT

    万径人踪灭 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 1936  Solved: 1076[Submit][Status][Discuss] De ...

  3. bzoj 3160 万径人踪灭——FFT

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3160 似乎理解加深了. 用卷积算相同的位置:先把 a 赋成1. b 赋成0,卷积一遍:再把 ...

  4. bzoj 3160 万径人踪灭 —— FFT

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3160 求出关于一个位置有多少对对称字母,如果 i 位置有 f[i] 对,对答案的贡献是 2^ ...

  5. bzoj 3160: 万径人踪灭 manachar + FFT

    3160: 万径人踪灭 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 133  Solved: 80[Submit][Status][Discuss] ...

  6. 【BZOJ 4332】 4332: JSOI2012 分零食 (FFT+快速幂)

    4332: JSOI2012 分零食 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 119  Solved: 66 Description 这里是欢乐 ...

  7. 【codeforces 623E】dp+FFT+快速幂

    题目大意:用$[1,2^k-1]$之间的证书构造一个长度为$n$的序列$a_i$,令$b_i=a_1\ or\ a_2\ or\ ...\ or a_i$,问使得b序列严格递增的方案数,答案对$10^ ...

  8. P3321 [SDOI2015]序列统计 FFT+快速幂+原根

    \(\color{#0066ff}{ 题目描述 }\) 小C有一个集合S,里面的元素都是小于M的非负整数.他用程序编写了一个数列生成器,可以生成一个长度为N的数列,数列中的每个数都属于集合S.小C用这 ...

  9. [bzoj 1409] Password 矩阵快速幂+欧拉函数

    考试的时候想到了矩阵快速幂+快速幂,但是忘(bu)了(hui)欧拉定理. 然后gg了35分. 题目显而易见,让求一个数的幂,幂是斐波那契数列里的一项,考虑到斐波那契也很大,所以我们就需要欧拉定理了 p ...

随机推荐

  1. Linux下JDK Tomcat MySQL基本环境搭建

    1. 安装JDK wget http://download.oracle.com/otn-pub/java/jdk/8u181-b13/96a7b8442fe848ef90c96a2fad6ed6d1 ...

  2. java网络通信编程

    网络编程就是在两个或两个以上的设备(例如计算机)之间传输数据.程序员所作的事情就是把数据发送到指定的位置,或者接收到指定的数据,这个就是狭义的网络编程范畴.在发送和接收数据时,大部分的程序设计语言都设 ...

  3. Super超级ERP系统---(4)采购管理--采购单创建

    Erp系统中采购是系统必不可少的一部分,也就是ERP种的进货模块,超级ERP系统中的采购模块选选择采购供应商,然后选择进货商品的数量和采购价格,创建采购进货单 1.创建采购单 2.审核采购单 采购单创 ...

  4. 自定义安装MS Office Project2007会出错

    作者:朱金灿 来源:http://blog.csdn.net/clever101 今天使用虚拟光驱文件自定义安装MSOffice Project2007,如下图: 然后总是出现一个错误: 从网上找来一 ...

  5. hdu 2768 Cat vs. Dog 最大独立集 巧妙的建图

    题目分析: 一个人要不是爱狗讨厌猫的人,要不就是爱猫讨厌狗的人.一个人喜欢的动物如果离开,那么他也将离开.问最多留下多少人. 思路: 爱猫和爱狗的人是两个独立的集合.若两个人喜欢和讨厌的动物是一样的, ...

  6. [翻译]开源PostgreSQL监控工具OPM

    一个好消息:九月,PostgreSQL OPM开发小组发布了开源的PostgreSQL数据库监控套件的第一个RELEASE版本OPM v2.3.PostgreSQL是先进的高级数据库,但它的一个重要的 ...

  7. wp7图片上传服务器

    做一个wp7手机上传图片到服务器的功能,具体丝路是在手机端做一个照相或者选择图片的功能,点击上传,在服务器端做一个一般处理程序,接受上传的文件,存入文件夹,下面是主要代码: 手机端代码: /// &l ...

  8. UWP App Services in Windows 10

    1.AppServices in Universal Windows Platform(UWP) UWP 应用服务可以提供给另一个UWP应用.在Win10系统中,一个应用服务当作应用的一个方法和机制来 ...

  9. 深入jar包:从jar包中读取资源文件

    我们常常在代码中读取一些资源文件(比如图片,音乐,文本等等).在单独运行的时候这些简单的处理当然不会有问题.但是,如果我们把代码打成一个jar包以后,即使将资源文件一并打包,这些东西也找不出来了.看看 ...

  10. springboot-helloworld实现

    springboot快速入门 首先,建立一个空的项目 第二步: 建立一个springboot项目 第三步:添加依赖: <?xml version="1.0" encoding ...