bzoj 3160 万径人踪灭——FFT
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3160
似乎理解加深了。
用卷积算相同的位置;先把 a 赋成1、 b 赋成0,卷积一遍;再把 a 赋成0、 b 赋成1,卷积一遍;两个加起来就有了每个位置的值,它表示以该位置/2(/2的位置可以是裂缝)为对称轴的回文位置个数。
然后用马拉车把连续区间的情况去掉。
注意一下单个元素也要算上,因为有那种奇数的;马拉车里别忘了把单个元素减去。
因为FFT的两个数组是一样的,所以FFT一次,然后自己乘自己就行了。
虽然调了很久但其实也没什么要注意的。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define ll long long
#define db double
using namespace std;
const int N=1e5+,M=N<<,mod=1e9+;
const db pi=acos(-);
int n,r[M],len,ans,bin[N];
char ch[N],tc[N<<];
struct cpl{db x,y;}a[M],b[M],I;
cpl operator+ (cpl a,cpl b){return (cpl){a.x+b.x,a.y+b.y};}
cpl operator- (cpl a,cpl b){return (cpl){a.x-b.x,a.y-b.y};}
cpl operator* (cpl a,cpl b){return (cpl){a.x*b.x-a.y*b.y,a.x*b.y+a.y*b.x};}
void upd(int &x){x>=mod?x-=mod:;x<?x+=mod:;}
void fft(cpl *a,bool fx)
{
for(int i=;i<len;i++)
if(i<r[i])swap(a[i],a[r[i]]);
for(int R=;R<=len;R<<=)//<<=1
{
int m=R>>;
cpl Wn=(cpl){ cos(pi/m),fx?-sin(pi/m):sin(pi/m) };
for(int i=;i<len;i+=R)
{
cpl w=I;
for(int j=;j<m;j++,w=w*Wn)//w=w*Wn
{
cpl tmp=w*a[i+m+j];
a[i+m+j]=a[i+j]-tmp;
a[i+j]=a[i+j]+tmp;
}
}
}
}
void manachar()
{
int m=(n<<)-;
for(int i=,j=;j<n;i+=,j++)
tc[i]=ch[j],tc[i+]=',';
int id=;
r[]=;ans--;
for(int i=;i<m;i++)
{
r[i]=;
if(id+r[id]>i)
{
r[i]=min(id+r[id]-i,r[(id<<)-i]);
}
if(id+r[id]<=i+r[i])
{
for(;i+r[i]<m&&i-r[i]>=&&tc[i+r[i]]==tc[i-r[i]];r[i]++);
r[i]--; id=i;
}
int tmp=(r[i]+(tc[i]==','))>>;//don't change r[i]!!!!!!
ans-=tmp+(tc[i]!=','); upd(ans);
}
}
int main()
{
I.x=;
scanf("%s",ch);n=strlen(ch);
bin[]=;
for(int i=,m=n+>>;i<=m;i++)bin[i]=bin[i-]<<,upd(bin[i]);
len=;
for(;len<=n<<;len<<=);
for(int i=;i<len;i++) r[i]=(r[i>>]>>)+((i&)?len>>:);
for(int i=;i<n;i++)
if(ch[i]=='a')a[i].x=;
fft(a,);
for(int i=;i<len;i++)a[i]=a[i]*a[i];
fft(a,);
for(int i=;i<n;i++)
if(ch[i]=='b')b[i].x=;
fft(b,);
for(int i=;i<len;i++)b[i]=b[i]*b[i];
fft(b,);
for(int i=;i<len;i++)//len
{
a[i].x=(int(a[i].x/len+0.5)+)>>;
b[i].x=(int(b[i].x/len+0.5)+)>>;
a[i].x+=b[i].x;
ans+=bin[(int)a[i].x]-; upd(ans);
}
manachar();
printf("%d\n",ans);
return ;
}
bzoj 3160 万径人踪灭——FFT的更多相关文章
- BZOJ 3160: 万径人踪灭 FFT+快速幂+manacher
BZOJ 3160: 万径人踪灭 题目传送门 [题目大意] 给定一个长度为n的01串,求有多少个回文子序列? 回文子序列是指从原串中找出任意个,使得构成一个回文串,并且位置也是沿某一对称轴对称. 假如 ...
- BZOJ 3160: 万径人踪灭 [fft manacher]
3160: 万径人踪灭 题意:求一个序列有多少不连续的回文子序列 一开始zz了直接用\(2^{r_i}-1\) 总-回文子串 后者用manacher处理 前者,考虑回文有两种对称形式(以元素/缝隙作为 ...
- bzoj 3160 万径人踪灭 FFT
万径人踪灭 Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 1936 Solved: 1076[Submit][Status][Discuss] De ...
- bzoj 3160 万径人踪灭 —— FFT
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3160 求出关于一个位置有多少对对称字母,如果 i 位置有 f[i] 对,对答案的贡献是 2^ ...
- bzoj 3160: 万径人踪灭 manachar + FFT
3160: 万径人踪灭 Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 133 Solved: 80[Submit][Status][Discuss] ...
- 【BZOJ】3160: 万径人踪灭 FFT+回文串
[题意]给定只含'a'和'b'字符串S,求不全连续的回文子序列数.n<=10^5. [算法]FFT+回文串 [题解]不全连续的回文子序列数=回文子序列总数-回文子串数. 回文子串数可以用回文串算 ...
- bzoj 3160: 万径人踪灭【FFT+manacher】
考虑正难则反,我们计算所有对称子序列个数,再减去连续的 这里减去连续的很简单,manacher即可 然后考虑总的,注意到关于一个中心对称的两点下标和相同(这样也能包含以空位为对称中心的方案),所以设f ...
- BZOJ 3160: 万径人踪灭
Description 一个ab串,问有多少回文子序列,字母和位置都对称,并且不连续. Sol FFT+Manacher. 不连续只需要减去连续的就可以了,连续的可以直接Manacher算出来. 其他 ...
- BZOJ 3160 万径人踪灭 解题报告
这个题感觉很神呀.将 FFT 和 Manacher 有机结合在了一起. 首先我们不管那个 “不能连续” 的条件,那么我们就可以求出有多少对字母关于某一条直线对称,然后记 $T_i$ 为关于直线 $i$ ...
随机推荐
- HDU 3449 Consumer
这是一道依赖背包问题.背包问题通常的解法都是由0/1背包拓展过来的,这道也不例外.我最初想到的做法是,由于有依赖关系,先对附件做个DP,得到1-w的附件背包结果f[i]表示i花费得到的最大收益,然后把 ...
- MySQL数据库基本操作(四)
在进行查询之前,我们要先建好关系表,并往数据表中插入些数据.为查询操作做好准备. 五张关系表的创建: #创建并进入数据库: mysql> CREATE DATABASE `info`; Quer ...
- 高通LCD驱动调试
本文转载自:http://www.itgo.me/a/x6305658852004979994/lcd%20qcom 来自 :http://blog.csdn.net/dacaozuo/article ...
- Linux bridge
CentOS bridge 配置: 1.创建br0配置文件 touch /etc/sysconfig/network-scripts/ifcfg-br0 2.修改bro配置文件 vi /etc/sy ...
- nohup后台运行jar与关闭
nohup 用途:LINUX命令用法,不挂断地运行命令. 语法:nohup Command [ Arg ... ] [ & ] 描述:nohup 命令运行由 Command 参数和任何相关 ...
- waitpid使用的一点问题
使用waipid的时候遇到了一个奇怪的问题,将情况简化后描述一下. 有关waitpid的基本介绍参见这里一下:http://www.cnblogs.com/mickole/p/3187770.html ...
- POJ2741 Colored Cubes
Description There are several colored cubes. All of them are of the same size but they may be colore ...
- jmeter ant 运行 提示Error occurred during initialization of VM
运行ant提示错误 网上找到的方法 将set HEAP= -Xms512m -Xmx1024m 改成set HEAP= -Xms512m -Xmx512m 保存后运行成功
- aodh M版本新特性 - queue between alarm evaluator and alarm notifier
之前alarm evaluator service and alarm notifier services之间的通信采用RPC的方式,消耗较大,增加work queue的方式可以获得更好的性能, + ...
- nova shelve
当一个虚机不需要使用的时候,可以将其 shelve 起来.该操作会创建该虚机的一个快照并传到 Glance 中,然后在 Hypervisor 上将该虚机删除,从而释放其资源. 其主要过程为: dest ...