真的分治fft
以前学的分治fft f[i]=sigma(f[i-x]*g[x]),其中g[x]已知
那么我们可以用cdq分治来做(l,mid 对mid+1,t的影响)
而现在的$f[i]=sum(f(i-x)*f(x))$
我们如果沿用刚才的方法 会发现有$f(t-h)$这一项
而$t-h>mid$是有可能的
所以我们要在后续处理这件事情
先将$f[l,mid]*f[l,mid]$乘起来
如果$t-h<h$ 还要算$f[1,t-h]*f[h,mid]$ 注意还要乘2
注意多次用fft 每次还原a,b数组 因为那个n是要比m大的,所以只清空到m的0是有问题的
1e5的数据开O2要2s 预料之中了
- #include <bits/stdc++.h>
- using namespace std;
- #define rint register int
- #define IL inline
- #define rep(i,h,t) for (rint i=h;i<=t;i++)
- #define dep(i,t,h) for (rint i=t;i>=h;i--)
- struct cp{
- double a,b;
- };
- const int N=3e5+;
- int n,m,l,r[N],f[N];
- int a[N],b[N],w[N],G=;
- const int mo=;
- const int p=mo;
- IL int fsp(rint x,rint y)
- {
- rint ans=;
- while (y)
- {
- if (y&) ans=(1ll*ans*x)%mo;
- x=(1ll*x*x)%mo;
- y>>=;
- }
- return ans;
- }
- void fft(int *a,int o)
- {
- for (int i=;i<n;i++)
- if (i>r[i]) swap(a[i],a[r[i]]);
- for (rint i=;i<n;i*=)
- {
- rint wn=fsp(G,(p-)/(i*)); w[]=;
- rep(j,,i-) w[j]=(1ll*w[j-]*wn)%p;
- for (rint j=;j<n;j+=(i*))
- {
- rint *x=a+j,*y=a+i+j;
- for (rint k=;k<i;k++)
- {
- const int t=(1ll*w[k]*y[k])%p;
- y[k]=x[k]-t;
- if (y[k]<) y[k]+=p;
- if (y[k]>p) y[k]-=p;
- x[k]=x[k]+t;
- if (x[k]>p) x[k]-=p;
- }
- }
- }
- if (o==-)
- {
- reverse(&a[],&a[n]);
- for (int i=,inv=fsp(n,p-);i<n;i++)
- a[i]=1ll*a[i]*inv%p;
- }
- }
- void query()
- {
- l=;
- for (n = ; n <= m; n <<= ) l++;
- for (int i=;i<n;i++) r[i]=(r[i/]/)|((i&)<<(l-));
- fft(a,),
- fft(b,);
- for (int i=;i<n;i++) a[i]=1ll*a[i]*b[i]%p;
- fft(a,-);
- }
- #define mid ((h+t)/2)
- IL void js(rint &x,rint y)
- {
- x+=y;
- x%=mo;
- }
- void cdq_fz(int h,int t)
- {
- if (h==t) return;
- cdq_fz(h,mid);
- if (t-h<h)
- {
- n=m=t-h+(mid-h+);
- rep(i,,t-h) a[i-]=f[i];
- rep(i,h,mid) b[i-h]=f[i];
- query();
- rep(i,mid+,t)
- if (i-h->=) js(f[i],(*a[i-h-])%mo);
- rep(i,,n) a[i]=b[i]=;
- }
- n=m=*(mid-h+);
- rep(i,h,mid) a[i-h]=b[i-h]=f[i];
- query();
- rep(i,mid+,t)
- if (i-(*h+)>=) js(f[i],a[i-(*h+)]);
- rep(i,,n) a[i]=b[i]=;
- cdq_fz(mid+,t);
- }
- int main()
- {
- freopen("1.in","r",stdin);
- freopen("1.out","w",stdout);
- ios::sync_with_stdio(false);
- int k;
- cin>>k;
- f[]=; f[]=;
- cdq_fz(,k);
- cout<<f[k]<<endl;
- return ;
- }
对拍
- #include <bits/stdc++.h>
- using namespace std;
- #define rep(i,h,t) for (int i=h;i<=t;i++)
- const int mo=;
- int f[];
- int main()
- {
- freopen("1.in","r",stdin);
- freopen("2.out","w",stdout);
- ios::sync_with_stdio(false);
- int n;
- cin>>n;
- f[]=; f[]=;
- rep(i,,n)
- rep(k,,i-)
- f[i]+=(1ll*f[k]*f[i-k-])%mo,f[i]%=mo;
- cout<<f[n]<<endl;
- return ;
- }
还有说多项式右移
f=f*f>>1+g
真的分治fft的更多相关文章
- [学习笔记]分治FFT
一般的分治FFT是指: https://www.luogu.org/problemnew/show/P4721 考虑后面的f和前面的f有关系,但是贡献可以分着计算,逐一累计上去. 考虑cdq分治.算出 ...
- LOJ#565. 「LibreOJ Round #10」mathematican 的二进制 分治,FFT,概率期望
原文链接www.cnblogs.com/zhouzhendong/p/LOJ565.html 前言 标算真是优美可惜这题直接暴力FFT算一算就solved了. 题解 首先,假装没有进位,考虑解决这个问 ...
- BNUOJ 51279[组队活动 Large](cdq分治+FFT)
传送门 大意:ACM校队一共有n名队员,从1到n标号,现在n名队员要组成若干支队伍,每支队伍至多有m名队员,求一共有多少种不同的组队方案.两个组队方案被视为不同的,当且仅当存在至少一名队员在两种方案中 ...
- hdu 5730 Shell Necklace [分治fft | 多项式求逆]
hdu 5730 Shell Necklace 题意:求递推式\(f_n = \sum_{i=1}^n a_i f_{n-i}\),模313 多么优秀的模板题 可以用分治fft,也可以多项式求逆 分治 ...
- BZOJ 4555: [Tjoi2016&Heoi2016]求和 [分治FFT 组合计数 | 多项式求逆]
4555: [Tjoi2016&Heoi2016]求和 题意:求\[ \sum_{i=0}^n \sum_{j=0}^i S(i,j)\cdot 2^j\cdot j! \\ S是第二类斯特林 ...
- 分治FFT的三种含义
分治FFT是几个算法的统称.它们之间并无关联. 分治多项式乘法 问题如求\(\prod_{i=1}^na_ix+b\). 若挨个乘复杂度为\(O(n^2\log n)\),可分治做这件事,复杂度为\( ...
- 【XSY2666】排列问题 DP 容斥原理 分治FFT
题目大意 有\(n\)种颜色的球,第\(i\)种有\(a_i\)个.设\(m=\sum a_i\).你要把这\(m\)个小球排成一排.有\(q\)个询问,每次给你一个\(x\),问你有多少种方案使得相 ...
- 【XSY2887】【GDOI2018】小学生图论题 分治FFT 多项式exp
题目描述 在一个 \(n\) 个点的有向图中,编号从 \(1\) 到 \(n\),任意两个点之间都有且仅有一条有向边.现在已知一些单向的简单路径(路径上任意两点各不相同),例如 \(2\to 4\to ...
- prime distance on a tree(点分治+fft)
最裸的点分治+fft,调了好久,太菜了.... #include<iostream> #include<cstring> #include<cstdio> #inc ...
随机推荐
- Nginx和apache服务器中php运行方式
PHP5的CGI方式的一大优势是内置了FastCGI的支持,只需指明绑定的地址和端口参数便可以以FastCGI的方式运行,如下: php-cgi -b 127.0.0.1:9000 配置Nginx的P ...
- 019_Mac实用的图像备份工具
一.mac上有一个非常好用的图像备份工具
- ansible笔记(11):初识ansible playbook(二)
ansible笔记():初识ansible playbook(二) 有前文作为基础,如下示例是非常容易理解的: --- - hosts: test211 remote_user: root tasks ...
- gcc/g++基本命令
gcc & g++现在是gnu中最主要和最流行的c & c++编译器 .g++是c++的命令,以.cpp为主,对于c语言后缀名一般为.c.这时候命令换做gcc即可.其实是无关紧要的.其 ...
- 前端 -----02 body标签中相关标签
今日内容: 字体标签: h1~h6.<font>.<u>.<b>.<strong><em>.<sup>.<sub> ...
- ActiveMQ在Windows下的安装与启动(懒人专属)
其实这些ActiveMQ官网都有,但是如果你懒得看官网,那就直接看这吧! 1. 官网下载最新的ActiveMQ安装包 apache-activemq-x.x.x-bin.zip并解压 2.进入安装 ...
- tornado的异步效果
第一种方式: import tornado.ioloop import tornado.web from tornado import gen from tornado.concurrent impo ...
- LNMP环境部署
说明: 操作系统:CentOS 5.6 32位 准备篇: 一.配置好IP.DNS .网关,确保使用远程连接工具能够连接服务器 二.配置防火墙,开启80端口.3306端口 vi /etc/sysconf ...
- JS将图片转换成Base64码
直接上代码 html页面代码 <!DOCTYPE html> <html lang="en"> <head> <meta charset= ...
- python-进程池与线程池,协程
一.进程池与线程池 实现并发的手段有两种,多线程和多进程.注:并发是指多个任务看起来是同时运行的.主要是切换+保存状态. 当我们需要执行的并发任务大于cpu的核数时,我们需要知道一个操作系统不能无限的 ...