【BZOJ3160】万径人踪灭(FFT,Manacher)

题面

BZOJ

题解

很容易想到就是满足条件的子序列个数减去回文子串的个数吧。。。

至于满足条件的子序列

我们可以依次枚举对称轴

如果知道关于这个位置对称的位置的组数

就很容易算了(直接\(2^k-1\))

而关于这个位置对称是什么东西?

\(s[x-i]=s[x+i]\)

也就是说,如果两个位置关于\(x\)位置对称,那么

\((x-i)+(x+i)=2x\)

也就是两个位置的坐标的和等于\(2x\)

这个玩意不就像一个卷积卷积了?

那么,\(a,b\)分开考虑

如果这个位置上有相应的字母就是\(1\)

如果两个位置都有\(1\)

那么,卷积\(x+y\)位置上就会有\(1\)

这样就可以算出前面要求的东西了

至于回文子串的个数?

\(Manacher\)呀

滑稽呀,马拉车写挂,身败名裂

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<set>
#include<map>
#include<vector>
#include<queue>
#include<complex>
using namespace std;
#define ll long long
#define RG register
#define MAX 500000
#define MOD 1000000007
const double Pi=acos(-1);
inline int read()
{
RG int x=0,t=1;RG char ch=getchar();
while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
if(ch=='-')t=-1,ch=getchar();
while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
return x*t;
}
int len;
char s[MAX];
int p[MAX],N,M;
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[i+p[i]]==s[i-p[i]])++p[i];
if(i+p[i]>mx)id=i,mx=p[i]+i;
}
ll ret=0;
for(int i=1;i<=len+len;++i)ret=(ret+p[i]/2)%MOD;
return ret;
}
int r[MAX],l;
complex<double> a[MAX],b[MAX];
ll f[MAX],tw[MAX],ans=0;
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;
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;
ans=(ans-Manacher()+MOD)%MOD;
printf("%lld\n",ans);
return 0;
}

【BZOJ3160】万径人踪灭(FFT,Manacher)的更多相关文章

  1. BZOJ3160:万径人踪灭(FFT,Manacher)

    Solution $ans=$回文子序列$-$回文子串的数目. 后者可以用$manacher$直接求. 前者设$f[i]$表示以$i$为中心的对称的字母对数. 那么回文子序列的数量也就是$\sum_{ ...

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

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

  3. P4199 万径人踪灭 FFT + manacher

    \(\color{#0066ff}{ 题目描述 }\) \(\color{#0066ff}{输入格式}\) 一行,一个只包含a,b两种字符的字符串 \(\color{#0066ff}{输出格式}\) ...

  4. BZOJ3160 万径人踪灭(FFT+manacher)

    容易想到先统计回文串数量,这样就去掉了不连续的限制,变为统计回文序列数量. 显然以某个位置为对称轴的回文序列数量就是2其两边(包括自身)对称相等的位置数量-1.对称有啥性质?位置和相等.这不就是卷积嘛 ...

  5. BZOJ3160 万径人踪灭 【fft + manacher】

    题解 此题略神QAQ orz po神牛 由题我们知道我们要求出: 回文子序列数 - 连续回文子串数 我们记为ans1和ans2 ans2可以用马拉车轻松解出,这里就不赘述了 问题是ans1 我们设\( ...

  6. BZOJ 3160: 万径人踪灭 FFT+快速幂+manacher

    BZOJ 3160: 万径人踪灭 题目传送门 [题目大意] 给定一个长度为n的01串,求有多少个回文子序列? 回文子序列是指从原串中找出任意个,使得构成一个回文串,并且位置也是沿某一对称轴对称. 假如 ...

  7. BZOJ3160 万径人踪灭 字符串 多项式 Manachar FFT

    原文链接http://www.cnblogs.com/zhouzhendong/p/8810140.html 题目传送门 - BZOJ3160 题意 给你一个只含$a,b$的字符串,让你选择一个子序列 ...

  8. Luogu4199 万径人踪灭 FFT、Manacher

    传送门 先不考虑”不是连续的一段“这一个约束条件.可以知道:第$i$位与第$j$位相同,可以对第$\frac{i+j}{2}$位置上产生$1$的贡献(如果$i+j$为奇数表明它会对一条缝产生$1$的贡 ...

  9. 万径人踪灭(FFT+manacher)

    传送门 这题--我觉得像我这样的菜鸡选手难以想出来-- 题目要求求出一些子序列,使得其关于某个位置是对称的,而且不能是连续一段,求这样的子序列的个数.这个直接求很困难,但是我们可以先求出所有关于某个位 ...

  10. bzoj 3160: 万径人踪灭【FFT+manacher】

    考虑正难则反,我们计算所有对称子序列个数,再减去连续的 这里减去连续的很简单,manacher即可 然后考虑总的,注意到关于一个中心对称的两点下标和相同(这样也能包含以空位为对称中心的方案),所以设f ...

随机推荐

  1. phpMyAdmin的使用

    phpMyAdmin的使用 安装MySQL数据库后,用户即可在命令行提示符下进行创建数据库和数据表等各种操作,但这种方法非常麻烦,而且需要有专业的SQL语言知识.PHP官方开发了一个类似于SQL Se ...

  2. CentOS 7 使用iptables防火墙

    # 停止firewalld服务 systemctl stop firewalld systemctl mask firewalld # 安装iptables-services yum install ...

  3. PHP die与exit的区别

    最近听见有人说die和exit区别,bula~bula.决心一探究竟. 翻了翻PHP 5.6的源码(源码的位置为zend目录下zend_language_scanner.l大约是1014~1020行) ...

  4. Android Stutio 3.0 - Gradle sync failed

    0.Android Studio 权威教程 (url:http://blog.csdn.net/column/details/zsl-androidstudio.html) 1. 项目老是报错: Gr ...

  5. Mysql字符串截取总结:left()、right()、substring()、substring_index()

    同步首发:http://www.yuanrengu.com/index.php/20171226.html 在实际的项目开发中有时会有对数据库某字段截取部分的需求,这种场景有时直接通过数据库操作来实现 ...

  6. ireport报表学习

    常用组件介绍: 制作一个报表一般四个组件比较常用,下面分别介绍 Rectangle:用于画表格的样式,整个表格的样式使用次组件做出来的,本控件表现为一个黑色矩形框,多个黑色矩形框排在一起可以组合出来任 ...

  7. C#委托与事件--简单笔记

    委托 简单记录点东西 适合似懂非懂的朋友看看 委托类型用来定义和响应应用程序中的回调. 借此可以设计各种有面向对象特性的代码模式.下面要说的事件在我看来就是委托的一种实现,再深一步讲,利用委托加事件, ...

  8. 试用MarkDown

    自定义界面风格 可以在设置中选择日间,或者夜间模式进行定义.具体的定义项的说明,可以查看菜单栏 (Windows版本位于托盘按钮上) 自定义的帮助. MarkEditor几乎所有跟色彩有关的界面,都已 ...

  9. Https访问

    Let's Encrypt是很火的一个免费SSL证书发行项目,自动化发行证书,证书有90天的有效期.适合个人使用或者临时使用,不用再忍受自签发证书不受浏览器信赖的提示.去年VPS侦探曾经说过Let's ...

  10. IOS 使用cocoapods后无法导入头文件问题

    IOS 使用cocoapods后无法导入头文件问题 这时候如果你发现import的时候没有提示AFN e t wo r k i n g.h的文件,可以在target-Build Settings下修改 ...