BZOJ3160【万径人踪灭】 【FFT】
。。恩 打了四五遍 不会也背出来了。。
BZOJ3160 【听说时限紧?转C++的优势么?】
上AC代码 fft
/*Problem: 3160
User: cyz666
Language: C++
Result: Accepted
Time:1992 ms
Memory:18492 kb
****************************************************************/ #include <bits/stdc++.h>
#define LL long long
const LL mo=;
const double pi=acos(-1.0);
using namespace std;
struct cp{
double x,y;
cp(double a=,double b=):x(a),y(b){}
//cp(double a=0,double b=0){x=a,y=b;}
}a[],b[],W[];
int h[],rev[],f[],c[],n,x,m;
char s; LL ans;
cp operator +(cp a,cp b){
cp c(a.x+b.x,a.y+b.y);
return c;
}
cp operator *(cp a,cp b){
cp c(a.x*b.x-a.y*b.y,a.x*b.y+a.y*b.x);
return c;
}
cp operator -(cp a,cp b){
return (cp){a.x-b.x,a.y-b.y};
}
void fft(cp a[],int n,int d=){
if (d<) reverse(a+,a+n);
for (int i=;i<n;++i)
if (i<rev[i]) swap(a[i],a[rev[i]]);
for (int i=;i<n/;++i)
W[i]=cp(cos(*pi/n*i),sin(*pi/n*i));
for (int m=,k=;m<=n;k=m,m<<=)
for (int i=;i<n;i+=m)
for (int j=i;j<i+k;++j){
cp u=a[j],v=a[j+k]*W[n/m*(j-i)];
a[j]=u+v,a[j+k]=u-v;
}
if (d<) for (int i=;i<n;++i) a[i].x/=n;
}
int main(){
while (scanf("%c",&s)&&isalpha(s))
s=='a'?c[++++n]=:c[++++n]=;
c[]=-; c[n+]=-;
for (int i=;i<=n;++i){
if (x+f[x]>i) f[i]=min(f[x+x-i],x+f[x]-i);
while (c[i+f[i]]==c[i-f[i]]) ++f[i]; --f[i];
if (i+f[i]>x+f[x]) x=i;
ans+=f[i]/; if (ans>=mo) ans-=mo;
}
m=ceil((log(n)/log())); m=<<m;
for (int i=;i<m;++i)rev[i]=(rev[i>>]>>)+(m>>)*(i&);
x=; for (int i=;i<=n;++++i) c[++x]=c[i]; n=x;
for (int i=;i<=n;++i) c[i]==?a[i].x=:b[i].x=;
fft(a,m); fft(b,m);
for (int i=;i<m;++i) a[i]=a[i]*a[i],b[i]=b[i]*b[i];
fft(a,m,-); fft(b,m,-);
h[]=; for (int i=;i<=n;++i)h[i]=(h[i-]+h[i-])%mo;
int x; ans=mo-ans;
for (int i=;i<n+n;++i){
x=round(a[i].x+b[i].x);
ans+=h[x+>>]-; if (ans>=mo) ans-=mo;
}
ans=(ans-n++mo)%mo;
printf("%lld",ans);
return ;
}
KriTo
然后 顺手写了个ntt板子扔这(没用题目测过对不对)
mo的原根g的定义:g^1,g^2,...,g^(mo-1) 在%mo意义下各不相同。
#include <bits/stdc++.h>
#define LL long long
using namespace std;
int g1,g2,N,n,k,x,W[],a[],b[],rev[],mo1,mo2;
LL po(LL x,LL y,LL mo){
LL z=; if (y<) y=y%(mo-)+mo-;
for (;y;y>>=,x=x*x%mo)
if (y&) z=z*x%mo;
return z;
}
int getg(LL mo){
LL y=mo-,x=floor(sqrt(y)); int fl;
for (int g=;;++g){
fl=;
for (int i=;i<=x;++i) if (!(y%i))
if (po(g,i,mo)==||po(g,y/i,mo)==) {fl=;break;}
if (fl) return g;
}
}
void ntt(int a[],int n,int d,int mo,int G){ //n整除(mo-1)
if (d<) reverse(a+,a+n);
for (int i=;i<n;++i)
if (i<rev[i]) swap(a[i],a[rev[i]]);
W[]=; LL X=po(G,(mo-)/n,mo);
for (int i=;i<n/;++i) W[i]=X*W[i-]%mo;
for (int m=,k=;m<=n;k=m,m<<=)
for (int i=;i<n;i+=m)
for (int j=i;j<i+k;++j){
int u=a[j],v=1ll*a[j+k]*W[n/m*(j-i)]%mo;
a[j]=u+v>=mo?u+v-mo:u+v;
a[j+k]=u-v<?u-v+mo:u-v;
}
if (d<){
X=po(n,mo-,mo);
for (int i=;i<n;++i) a[i]=X*a[i]%mo;
}
}
int main(){
mo1=; mo2=;
g1=getg(mo1); g2=getg(mo2);
scanf("%d%d",&n,&k); W[]=;
for (int i=;i<=n;++i)
scanf("%d",&x),a[x]=,b[x]=;
N=;
for (int i=;i<N;++i) rev[i]=rev[i>>]>>|(i&?N>>:);
ntt(a,N,,mo1,g1); ntt(b,N,,mo2,g2);
for (int i=;i<N;++i)
a[i]=po(a[i],k,mo1),b[i]=po(b[i],k,mo2);
ntt(a,N,-,mo1,g1); ntt(b,N,-,mo2,g2);
for (int i=;i<N;++i){
if (a[i]<) a[i]+=mo1;
if (b[i]<) b[i]+=mo2;
}
for (int i=;i<N;++i) if (a[i]||b[i]) printf("%d ",i); puts("");
return ;
}
AsuNa
若多项式相乘的最高次为n, 则FFT,NTT的数组大小要开到>n的最小的2的幂。 即 1<<(int)ceil(log(n+1)/log(2))
给几个模数:
1004535809=479*2^21+1, 原根=3
998244353=7*17*2^23+1 ,原根=3
469762049=7*2^26+1 ,原根=3
BZOJ3160【万径人踪灭】 【FFT】的更多相关文章
- BZOJ3160:万径人踪灭(FFT,Manacher)
Solution $ans=$回文子序列$-$回文子串的数目. 后者可以用$manacher$直接求. 前者设$f[i]$表示以$i$为中心的对称的字母对数. 那么回文子序列的数量也就是$\sum_{ ...
- BZOJ3160 万径人踪灭 字符串 多项式 Manachar FFT
原文链接http://www.cnblogs.com/zhouzhendong/p/8810140.html 题目传送门 - BZOJ3160 题意 给你一个只含$a,b$的字符串,让你选择一个子序列 ...
- 【bzoj3160】万径人踪灭 FFT
题目:http://www.lydsy.com/JudgeOnline/problem.php?id=3160 我是一个傻叉 微笑脸 #include<bits/stdc++.h> #de ...
- BZOJ3160 万径人踪灭(FFT+manacher)
容易想到先统计回文串数量,这样就去掉了不连续的限制,变为统计回文序列数量. 显然以某个位置为对称轴的回文序列数量就是2其两边(包括自身)对称相等的位置数量-1.对称有啥性质?位置和相等.这不就是卷积嘛 ...
- BZOJ3160 万径人踪灭 【fft + manacher】
题解 此题略神QAQ orz po神牛 由题我们知道我们要求出: 回文子序列数 - 连续回文子串数 我们记为ans1和ans2 ans2可以用马拉车轻松解出,这里就不赘述了 问题是ans1 我们设\( ...
- BZOJ3160: 万径人踪灭(FFT,回文自动机)
BZOJ传送门: 解题思路: FFT在处理卷积时可以将自己与自己卷,在某一种字母上标1其他标0,做字符集次就好了. (回文就是直接对称可以联系偶函数定义理解,根据这个性质就可以将字符串反向实现字符串匹 ...
- [bzoj3160]万径人踪灭_FFT_Manacher
万径人踪灭 bzoj-3160 题目大意:给定一个ab串.求所有的子序列满足:位置和字符都关于某条对称轴对称而且不连续. 注释:$1\le n\le 10^5$. 想法: 看了大爷的题解,OrzOrz ...
- 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+快速幂+manacher
BZOJ 3160: 万径人踪灭 题目传送门 [题目大意] 给定一个长度为n的01串,求有多少个回文子序列? 回文子序列是指从原串中找出任意个,使得构成一个回文串,并且位置也是沿某一对称轴对称. 假如 ...
随机推荐
- POJ 1724 二维费用最短路
题目大意:有N个城市,编号1-N有R条路,每条路(单向)的起点为Si,终点为Di,长度为Li,如果要走这条路需要花Ti的钱现在你只有K元钱,求在不超支的前提下,从1走到N需要的最短距离 这里总是希望路 ...
- 【链表】2017多校训练三 HDU 6058 Kanade's sum
acm.hdu.edu.cn/showproblem.php?pid=6058 [题意] 给定一个排列,计算 [思路] 计算排列A中每个数的贡献,即对于每个ai,计算有ni个区间满足ai是区间中的第k ...
- To_Date函数用法
spl> select * from emp where dates between to_date('2007-06-12 10:00:0 ...
- 虫食算(codevs 1064)
题目描述 Description 所谓虫食算,就是原先的算式中有一部分被虫子啃掉了,需要我们根据剩下的数字来判定被啃掉的字母.来看一个简单的例子: 43#9865#045 + 8468#6 ...
- [NOIP2002] 提高组 洛谷P1033 自由落体
题目描述 在高为 H 的天花板上有 n 个小球,体积不计,位置分别为 0,1,2,….n-1.在地面上有一个小车(长为 L,高为 K,距原点距离为 S1).已知小球下落距离计算公式为 d=1/2*g* ...
- 积累js中的一些问题及解决方案
一.取字符串的第i位不兼容的问题 1.问题:对于字符串str来说,要获取第i位,常见的是str[i],但是在低版本的浏览器中不兼容,例如ie7. 2.解决:使用str.charAt(i); 二.使用定 ...
- Codeforces 938G(cdq分治+可撤销并查集+线性基)
题意: 有一个无向连通图,支持三个操作: 1 x y d : 新建一条x和y的无向边,长度为d 2 x y :删除x和y之间的无向边 3 x y :询问x到y的所有路径中(可以绕环)最短的 ...
- Java中的数字
以下内容引用自http://wiki.jikexueyuan.com/project/java/numbers.html: 通常情况下,当处理数字时,使用原始数据类型,如byte,int,long,d ...
- Jmeter参数Parameters和Body Data区别
1.如图: 2.有文章说,Parameters是get的参数:Body Data是post的参数:get的参数存在于url中,post的参数存在于body中: 但是我使用jmeter3.3版本测试 ...
- 基于Hexo + Git + Nginx的博客发布
进过上一篇<树莓派搭建私人服务器>,我们已经有一个私人服务器了,现在需要做点什么实际事情了,先搭一个博客分享自己的经验吧. 相关文章:1.<树莓派搭建私人服务器>(http:/ ...