bzoj 3160 万径人踪灭 —— FFT
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3160
求出关于一个位置有多少对对称字母,如果 i 位置有 f[i] 对,对答案的贡献是 2^f[i] - 1;
然后减去连续的,用 manachar 求出回文长度,每个位置作为边界都是一种不合法情况;
求对称,首先把字符串中间穿插字符 '$',于是字符串的长度变成2倍;
考虑一对字母 s[x],s[y],如果 s[x] = s[y],其对称中心是 (x+y)/2;
放在加入字符后的字符串中,对称中心就是 x+y;
所以可以看出卷积了:f[i] = ∑(0<=j<=i) (s[j]==s[i-j]),其中 i 视为新字符串中的位置,j 和 i-j 视为原字符串中的位置;
注意卷积和 manachar 算的个数都要包括自己成对,否则判断挺麻烦...
这里卷积的两个多项式其实是一样的,所以只要用 FFT 算出一个,然后自己乘起来即可;
做下一步的时候注意清空,别忘了清空 n~lim 部分的值;
处理 bin 的边界是 n 而非 n-1,因为最多可能有 n 对。
(学习了 manachar 的简洁写法)
代码如下:
- #include<iostream>
- #include<cstdio>
- #include<cstring>
- #include<algorithm>
- #include<cmath>
- using namespace std;
- typedef double db;
- int const xn=(<<),mod=1e9+;
- db const Pi=acos(-1.0);
- int n,rev[xn],lim=,l,len[xn],bin[xn],c[xn];
- char ch[xn];
- struct com{db x,y;}a[xn],b[xn],aa[xn];
- com operator + (com a,com b){return (com){a.x+b.x,a.y+b.y};}
- com operator - (com a,com b){return (com){a.x-b.x,a.y-b.y};}
- com operator * (com a,com b){return (com){a.x*b.x-a.y*b.y,a.x*b.y+b.x*a.y};}
- int upt(int x){while(x>=mod)x-=mod; while(x<)x+=mod; return x;}
- void fft(com *a,int tp)
- {
- for(int i=;i<lim;i++)
- if(i<rev[i])swap(a[i],a[rev[i]]);
- for(int mid=;mid<lim;mid<<=)
- {
- com wn=(com){cos(Pi/mid),tp*sin(Pi/mid)};
- for(int j=,len=(mid<<);j<lim;j+=len)
- {
- com w=(com){,};
- for(int k=;k<mid;k++,w=w*wn)
- {
- com x=a[j+k],y=w*a[j+mid+k];
- a[j+k]=x+y; a[j+mid+k]=x-y;
- }
- }
- }
- }
- void solve()
- {
- for(int i=;i<n;i++)a[i].x=(ch[i]=='a');
- fft(a,);
- for(int i=;i<lim;i++)b[i]=a[i]*a[i];
- for(int i=;i<n;i++)a[i].x=(ch[i]=='b'),a[i].y=;//y=0
- for(int i=n;i<lim;i++)a[i].x=,a[i].y=;//!!
- fft(a,);
- for(int i=;i<lim;i++)b[i]=b[i]+a[i]*a[i];
- fft(b,-);
- for(int i=;i<n+n;i++)c[i]=(c[i]+(int)(b[i].x/lim+0.5))%mod;
- }
- char s[xn];
- int manachar()//+i self
- {
- int mx=,id=,ret=; s[]='$';
- for(int i=;i<=n+n;i++)
- if(i%==)s[i]='$';
- else s[i]=ch[i>>];
- for(int i=;i<=n+n;i++)
- {
- if(i<mx)len[i]=min(mx-i,len[id*-i]);
- while(i-len[i]>=&&i+len[i]<=n+n&&s[i-len[i]]==s[i+len[i]])len[i]++;
- if(i+len[i]>mx)mx=i+len[i],id=i;
- ret=upt(ret+len[i]/);
- }
- return ret;
- }
- int main()
- {
- scanf("%s",ch); n=strlen(ch);
- while(lim<=n+n)lim<<=,l++;//
- for(int i=;i<lim;i++)
- rev[i]=((rev[i>>]>>)|((i&)<<(l-)));
- bin[]=;
- for(int i=;i<=n;i++)bin[i]=upt(bin[i-]+bin[i-]);
- solve();
- int ans=;
- for(int i=;i<n+n;i++)ans=upt(ans+bin[(c[i]+)>>]-);//+1 -1
- printf("%d\n",upt(ans-manachar()));
- 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
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3160 似乎理解加深了. 用卷积算相同的位置:先把 a 赋成1. b 赋成0,卷积一遍:再把 ...
- bzoj 3160 万径人踪灭 FFT
万径人踪灭 Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 1936 Solved: 1076[Submit][Status][Discuss] De ...
- 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$ ...
随机推荐
- 查看java中的线程个数名称
查看java中的线程个数名称 package com.stono.thread2; import java.lang.management.ManagementFactory; import java ...
- 转: 写给想成为前端工程师的同学们 (from 360前端团队)
转自: http://www.75team.com/post/to-be-a-good-frontend-engineer.html 前端工程师是做什么的? 前端工程师是互联网时代软件产品研发 ...
- node开发自动刷新网页中的css和javascript
在已有node的环境下,安装browser-sync: npm install -g browser-sync 然后运行,默认本目录下(最后填写要监听的文件--本实例监听了css文件夹下面的所有css ...
- java性能监控工具jps-windows
jps Lists the instrumented Java Virtual Machines (JVMs) on the target system. This command is experi ...
- CSS3中的动画效果-------Day72
还记得么,在前面也曾实现过"仅仅用css让div动起来",还记得当时是怎么实现的么,是的,transition,针对的也比較局限,仅仅有旋转角度啊,长宽啊之类的,所以说,与其说是动 ...
- C#数据类型与数据库字段类型对应
数据库 C#程序 int int32 text string bigint int64 binary System.Byte[] bit Boolean char string datetime Sy ...
- iOS 获取图片某一点的颜色对象(UIColor*)。
- (UIColor *)colorAtPixel:(CGPoint)point { // Cancel if point is outside image coordinates if (!CGRe ...
- mysql could not be resolved: Name or service not known
问题: mysql DNS反解:skip-name-resolve 错误日志有类似警告: 1.120119 16:26:04 [Warning] IP address '192.168.1.10' c ...
- 搭建mysql主从集群的步骤
前提条件是:须要在linux上安装4个mysql数据库,都须要配置完对应的信息. 须要搭建: mysql 01: 主数据库 master mysql 02 : ...
- SICP 习题 (1.38)解题总结
SICP 习题1.38 紧跟着习题1.37的方向,要求我们用习题1.37中定义的cont-frac过程计算数学家欧拉大师在论文De Fractionibus Continuis 中提到的e-2的连分式 ...