bzoj3160(FFT+回文自动机)
题目描述
https://www.lydsy.com/JudgeOnline/problem.php?id=3160
题解
先把问题转化一下,我们要求的是非连续对称回文子序列。
ans=回文子序列数-回文子串数。
回文子串数可以用PAM或manachar求出来。
复习了一下PAM,用它求回文子串数和SAM一样,就是size[fa[i]]+=size[i],这时每一个节点代表的是所有它的后缀回文串。
然后怎么求回文子序列数。
考虑每一条对称轴,它能被谁贡献。
f[(i+j)/2]可以被i和j更新,当i和j是一种字符时。然后我们把前面的/2去掉,然后这个可以用卷积做。
最后我们发现对于一对字符会被统计两次,但是对于对称中心的字符只会被统计一次,所以我们/2时要向下取整。
坑点:PAM的size
last=ch[last][s[i]-'a'];size[last]++;
代码
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#define N 100009
using namespace std;
typedef long long ll;
const int mod=1e9+;
const double pai=acos(-1.0);
ll ans;
int len[N],cnt,last,fail[N],ch[N][],size[N];
int L,l,n,rev[N<<];
char s[N];
inline int rd(){
int x=;char c=getchar();bool f=;
while(!isdigit(c)){if(c=='-')f=;c=getchar();}
while(isdigit(c)){x=(x<<)+(x<<)+(c^);c=getchar();}
return f?-x:x;
}
inline int power(ll x,int y){
ll ans=;
while(y){
if(y&)ans=(ans*x)%mod;
x=(x*x)%mod;
y>>=;
}
return ans;
}
struct fs{
double x,y;
fs(){}
fs(double xx,double yy){x=xx;y=yy;}
fs operator +(const fs &b)const{return fs{x+b.x,y+b.y};}
fs operator -(const fs &b)const{return fs{x-b.x,y-b.y};}
fs operator *(const fs &b)const{return fs{x*b.x-y*b.y,x*b.y+y*b.x};}
}a[N<<],b[N<<];
inline void FFT(fs *a,int tag){
for(int i=;i<l;++i)if(rev[i]>i)swap(a[i],a[rev[i]]);
for(int i=;i<l;i<<=){
fs wn(cos(pai/i),tag*sin(pai/i));
for(int j=;j<l;j+=(i<<)){
fs w(,);
for(int k=;k<i;++k,w=w*wn){
fs x=a[j+k],y=w*a[k+i+j];
a[j+k]=x+y;a[i+j+k]=x-y;
}
}
}
}
int main(){
scanf("%s",s+);n=strlen(s+);
l=;L=;while(l<=(n<<))l<<=,++L;
for(int i=;i<l;++i)rev[i]=(rev[i>>]>>)|((i&)<<(L-));
for(int i=;i<=n;++i)if(s[i]=='a')a[i].x=;else b[i].x=;
FFT(a,);FFT(b,);
for(int i=;i<l;++i)a[i]=a[i]*a[i]+b[i]*b[i];FFT(a,-);
for(int i=;i<l;++i)a[i].x=(int)(a[i].x/l+0.1);
for(int i=;i<l;++i)ans=(ans+power(,ceil((double)a[i].x/))-)%mod;
cnt=last=;len[]=-;fail[]=;
for(int i=;i<=n;++i){
while(s[i-len[last]-]!=s[i])last=fail[last];
if(!ch[last][s[i]-'a']){
len[++cnt]=len[last]+;
int y=fail[last];
while(s[i-len[y]-]!=s[i])y=fail[y];
fail[cnt]=ch[y][s[i]-'a'];ch[last][s[i]-'a']=cnt;
}
last=ch[last][s[i]-'a'];size[last]++;
}
for(int i=cnt;i;--i)(size[fail[i]]+=size[i])%=mod;
for(int i=;i<=cnt;++i)ans=(ans-size[i]+mod)%mod;
cout<<ans;
return ;
}
bzoj3160(FFT+回文自动机)的更多相关文章
- BZOJ3160: 万径人踪灭(FFT,回文自动机)
BZOJ传送门: 解题思路: FFT在处理卷积时可以将自己与自己卷,在某一种字母上标1其他标0,做字符集次就好了. (回文就是直接对称可以联系偶函数定义理解,根据这个性质就可以将字符串反向实现字符串匹 ...
- URAL 2040 (回文自动机)
Problem Palindromes and Super Abilities 2 (URAL2040) 题目大意 给一个字符串,从左到右依次添加,询问每添加一个字符,新增加的回文串数量. 解题分析 ...
- URAL 2040 Palindromes and Super Abilities 2 (回文自动机)
Palindromes and Super Abilities 2 题目链接: http://acm.hust.edu.cn/vjudge/contest/126823#problem/E Descr ...
- 后缀自动机/回文自动机/AC自动机/序列自动机----各种自动机(自冻鸡) 题目泛做
题目1 BZOJ 3676 APIO2014 回文串 算法讨论: cnt表示回文自动机上每个结点回文串出现的次数.这是回文自动机的定义考查题. #include <cstdlib> #in ...
- [模板] 回文树/回文自动机 && BZOJ3676:[Apio2014]回文串
回文树/回文自动机 放链接: 回文树或者回文自动机,及相关例题 - F.W.Nietzsche - 博客园 状态数的线性证明 并没有看懂上面的证明,所以自己脑补了一个... 引理: 每一个回文串都是字 ...
- BZOJ2160拉拉队排练——回文自动机
题目描述 艾利斯顿商学院篮球队要参加一年一度的市篮球比赛了.拉拉队是篮球比赛的一个看点,好的拉拉队往往能帮助球队增加士气,赢得最终的比赛.所以作为拉拉队队长的楚雨荨同学知道,帮助篮球队训练好拉拉队有多 ...
- BZOJ2084[Poi2010]Antisymmetry——回文自动机
题目描述 对于一个01字符串,如果将这个字符串0和1取反后,再将整个串反过来和原串一样,就称作“反对称”字符串.比如00001111和010101就是反对称的,1001就不是.现在给出一个长度为N的0 ...
- BZOJ2342[Shoi2011]双倍回文——回文自动机
题目描述 输入 输入分为两行,第一行为一个整数,表示字符串的长度,第二行有个连续的小写的英文字符,表示字符串的内容. 输出 输出文件只有一行,即:输入数据中字符串的最长双倍回文子串的长度,如果双倍回文 ...
- 【XSY2715】回文串 树链剖分 回文自动机
题目描述 有一个字符串\(s\),长度为\(n\).有\(m\)个操作: \(addl ~c\):在\(s\)左边加上一个字符\(c\) \(addr~c\):在\(s\)右边加上一个字符 \(tra ...
随机推荐
- Tomcat web.xml配置参数详解
Apache Tomcat Configuration Reference - The Context Containerhttps://tomcat.apache.org/tomcat-5.5-do ...
- taro 与uni-app对比
https://www.jianshu.com/p/03e08399587e (copy)
- MySQL 字段内容区分大小写
数据由Oracle 迁入MySQL ,由于之前Oracle区分大小写,MySQL的配置使用了默认配置,导致一些数据导入失败,有的唯一键报错,冲突. 将测试过程记录在下面. 数据库版本:MySQL 5. ...
- java中解决小数精度问题
public class TestDouble { public static void main(String[] args) { Double d1 = 0.1; Double d2 = 0.2; ...
- Golang的channel使用以及并发同步技巧
在学习<The Go Programming Language>第八章并发单元的时候还是遭遇了不少问题,和值得总结思考和记录的地方. 做一个类似于unix du命令的工具.但是阉割了一些功 ...
- python学习笔记(12)--程序设计方法学
计算思维: 逻辑思维:推演和演绎 实证思维:实验和验证,引力波->实验 计算思维:设计和构造,计算机为代表,汉诺塔递归. 计算思维特征 抽象和自动化,抽象问题的计算过程,利用计算机自动化求解. ...
- layui内部使用jQuery
layui是基于jQuery的框架,本身自带jQuery 根据官方推荐,是使用自带的好一点 这里记一下内部使用jQuery的方法: layui.use('jquery', function(){ va ...
- Java HashMap的put操作(Java1.8)
https://www.cnblogs.com/JzedyBlogs/p/10208295.html 写得非常好: 这个是Java1.8 ------------------------------- ...
- Java多线程之Join方法阻塞线程
package org.study2.javabase.ThreadsDemo.status; /** * @Auther:GongXingRui * @Date:2018/9/19 * @Descr ...
- ADO.NET工具类(一)
using System; using System.Collections.Generic; using System.Text; using System.Data.SqlClient; usin ...