FFT,NTT 专题
学习傅里叶的基本性质及其代码,可以参考大神理解
还有 ACdream 的博客
贴一下NTT的模板:
- using namespace std;
- typedef long long ll;
- int n;
- const ll MOD=;
- const int N = ;
- const int g=;
- int len;
- ll A[N];
- long long a[N],b[N],wn[];
- long long q_pow(long long x,long long y,long long P)
- {
- long long ans=;
- while(y>)
- {
- if(y&)ans=ans*x%P;
- x=x*x%P;
- y>>=;
- }
- return ans;
- }
- void init()
- {
- for(int i=;i<;i++)
- {
- int t=<<i;
- wn[i]=q_pow(g,(MOD-)/t,MOD);
- }
- }
- ///雷德算法,2^M=len,将第i位的数与“i的二进制反转之后的位”的数交换
- void rader(long long F[],int len)
- {
- int j=len/;///模拟二进制反转进位的的位置
- for(int i=;i<len-;i++)
- {
- if(i<j)swap(F[i],F[j]);///该出手时就出手
- int k=len/;
- while(j>=k)
- {
- j-=k;
- k>>=;
- }
- if(j<k)j+=k;
- }
- }
- void NTT(long long F[],int len,int t)
- {
- int id=;
- rader(F,len);
- for(int h=;h<=len;h<<=)
- {
- id++;
- for(int j=;j<len;j+=h)
- {
- long long E=;
- for(int k=j;k<j+h/;k++)
- {
- long long u=F[k];
- long long v=(E*F[k+h/])%MOD;
- F[k]=(u+v)%MOD;
- F[k+h/]=((u-v)%MOD+MOD)%MOD;
- E=(E*wn[id])%MOD;
- }
- }
- }
- if(t==-)
- {
- for(int i=;i<len/;i++)swap(F[i],F[len-i]);
- long long ni=q_pow(len,MOD-,MOD);
- for(int i=;i<len;i++)F[i]=(F[i]%MOD*ni)%MOD;
- }
- }
- void work()///卷积,点乘,插值
- {
- NTT(a,len,);
- NTT(b,len,);
- for(int i=;i<len;i++)
- a[i]=(a[i]*b[i])%MOD;
- NTT(a,len,-);
- }
- int main()
- {
- #ifndef ONLINE_JUDGE
- freopen("in.txt","r",stdin);
- #endif
- init();
- int T_T;
- scanf("%d",&T_T);
- for(int kase=;kase<=T_T;kase++)
- {
- sc(n);
- len=;
- while(len<=*n)
- len<<=;
/**
这部分就是你对公式的变形并把他转化为卷积形式,分别存在a[],b[]里
*/
work();
}
return 0;
}
对于傅里叶运用的要点,要认真对待对下面卷积公式的理解
训练:
传送门:hdu 5829 Rikka with Subset
题意:给你一个数组A[],然后计算F[k],F[k]指A[]所有子集中,先对每个子集前k大的数的和,然后再对把所以子集所求值求和
思路:因为我也是初学,所以我找的一个大神的博客学习的http://blog.csdn.net/cqu_hyx/article/details/52194696
对于其中的几点,我做一点补充:
- f[k]计算的是第k大的数对答案的贡献,而比他大的数的贡献没有计算;不过只需要累加分f[1]..f[k-1]就是前k大的数的和了
- 对比以上卷积公式,我们得到的是 a[i]=2n-i/i! , b[i]=A[i]*(i-1)! ;如果我们b[0]=A[1]*0!,那么我们reverse一下,b[i]=b[n-i]了;在我们推导的f[k]公式里,f[k]是与a[i]*b[i+k]相关的,且i最大为(n-k),经过我们对b数组reverse,f[k]是与a[i]*b[(n-k)-i]相关的,这刚好和上面的卷积公式一致,所以我们可以放心ntt了。
- 由卷积公式可知,y[n-k]是a[i]*b[(n-k)-i]的卷积结果,而这个结果存在a[]里;并且f[k]也等于a[i]*b[(n-k)-i]的卷积,所以f[k]与y[n-k]即a[n-k]相关
- /**************************************************************
- Problem:hdu 5829 Rikka with Subset
- User: youmi
- Language: C++
- Result: Accepted
- Time:2605MS
- Memory:11804K
- ****************************************************************/
- //#pragma comment(linker, "/STACK:1024000000,1024000000")
- //#include<bits/stdc++.h>
- #include <iostream>
- #include <cstdio>
- #include <cstring>
- #include <algorithm>
- #include <map>
- #include <stack>
- #include <set>
- #include <sstream>
- #include <cmath>
- #include <queue>
- #include <deque>
- #include <string>
- #include <vector>
- #define zeros(a) memset(a,0,sizeof(a))
- #define ones(a) memset(a,-1,sizeof(a))
- #define sc(a) scanf("%d",&a)
- #define sc2(a,b) scanf("%d%d",&a,&b)
- #define sc3(a,b,c) scanf("%d%d%d",&a,&b,&c)
- #define scs(a) scanf("%s",a)
- #define sclld(a) scanf("%I64d",&a)
- #define pt(a) printf("%d\n",a)
- #define ptlld(a) printf("%I64d\n",a)
- #define rep(i,from,to) for(int i=from;i<=to;i++)
- #define irep(i,to,from) for(int i=to;i>=from;i--)
- #define Max(a,b) ((a)>(b)?(a):(b))
- #define Min(a,b) ((a)<(b)?(a):(b))
- #define lson (step<<1)
- #define rson (lson+1)
- #define eps 1e-6
- #define oo 0x3fffffff
- #define TEST cout<<"*************************"<<endl
- const double pi=*atan(1.0);
- using namespace std;
- typedef long long ll;
- int n;
- const ll MOD=;
- const int N = ;
- const int g=;
- int len;
- ll inv2;
- ll A[N];
- ll inv[N],fac[N],f[N],bit[N];
- long long a[N],b[N],wn[];
- long long q_pow(long long x,long long y,long long P)
- {
- long long ans=;
- while(y>)
- {
- if(y&)ans=ans*x%P;
- x=x*x%P;
- y>>=;
- }
- return ans;
- }
- void init()
- {
- for(int i=;i<;i++)
- {
- int t=<<i;
- wn[i]=q_pow(g,(MOD-)/t,MOD);
- }
- inv[]=inv[]=;
- rep(i,,1e5)
- inv[i]=(inv[i-]*q_pow(i,MOD-,MOD))%MOD;
- fac[]=fac[]=;
- rep(i,,1e5)
- fac[i]=(fac[i-]*i)%MOD;
- bit[]=;
- rep(i,,1e5)
- bit[i]=bit[i-]*%MOD;
- inv2=q_pow(,MOD-,MOD);
- }
- ///雷德算法,2^M=len,将第i位的数与“i的二进制反转之后的位”的数交换
- void rader(long long F[],int len)
- {
- int j=len/;///模拟二进制反转进位的的位置
- for(int i=;i<len-;i++)
- {
- if(i<j)swap(F[i],F[j]);///该出手时就出手
- int k=len/;
- while(j>=k)
- {
- j-=k;
- k>>=;
- }
- if(j<k)j+=k;
- }
- }
- void NTT(long long F[],int len,int t)
- {
- int id=;
- rader(F,len);
- for(int h=;h<=len;h<<=)
- {
- id++;
- for(int j=;j<len;j+=h)
- {
- long long E=;
- for(int k=j;k<j+h/;k++)
- {
- long long u=F[k];
- long long v=(E*F[k+h/])%MOD;
- F[k]=(u+v)%MOD;
- F[k+h/]=((u-v)%MOD+MOD)%MOD;
- E=(E*wn[id])%MOD;
- }
- }
- }
- if(t==-)
- {
- for(int i=;i<len/;i++)swap(F[i],F[len-i]);
- long long ni=q_pow(len,MOD-,MOD);
- for(int i=;i<len;i++)F[i]=(F[i]%MOD*ni)%MOD;
- }
- }
- void work()///卷积,点乘,插值
- {
- NTT(a,len,);
- NTT(b,len,);
- for(int i=;i<len;i++)
- a[i]=(a[i]*b[i])%MOD;
- NTT(a,len,-);
- }
- int main()
- {
- #ifndef ONLINE_JUDGE
- freopen("in.txt","r",stdin);
- #endif
- init();
- int T_T;
- scanf("%d",&T_T);
- for(int kase=;kase<=T_T;kase++)
- {
- sc(n);
- len=;
- while(len<=*n)
- len<<=;
- rep(i,,n)
- sclld(A[i]);
- sort(A+,A++n,greater<ll>());
- zeros(a);zeros(b);
- rep(i,,n-)
- a[i]=(bit[n-i]*inv[i])%MOD;
- rep(i,,n-)
- b[i]=(A[i+]*fac[i])%MOD;
- reverse(b,b+n);
- work();
- ll r=inv2;
- f[]=;
- rep(i,,n)
- {
- f[i]=a[n-i]*inv[i-]%MOD*r%MOD;
- r=r*inv2%MOD;
- f[i]=(f[i]+f[i-])%MOD;
- printf("%I64d ",f[i]);
- }
- puts("");
- }
- }
FFT,NTT 专题的更多相关文章
- FFT与NTT专题
先不管旋转操作,考虑化简这个差异值 $$begin{aligned}sum_{i=1}^n(x_i-y_i-c)^2&=sum_{i=1}^n(x_i-y_i)^2+nc^2-2csum_{i ...
- FFT \ NTT总结(多项式的构造方法)
前言.FFT NTT 算法 网上有很多,这里不再赘述. 模板见我的代码库: FFT:戳我 NTT:戳我 正经向:FFT题目解题思路 \(FFT\)这个玩意不可能直接裸考的..... 其实一般\(FF ...
- [学习笔记&教程] 信号, 集合, 多项式, 以及各种卷积性变换 (FFT,NTT,FWT,FMT)
目录 信号, 集合, 多项式, 以及卷积性变换 卷积 卷积性变换 傅里叶变换与信号 引入: 信号分析 变换的基础: 复数 傅里叶变换 离散傅里叶变换 FFT 与多项式 \(n\) 次单位复根 消去引理 ...
- FFT/NTT/MTT学习笔记
FFT/NTT/MTT Tags:数学 作业部落 评论地址 前言 这是网上的优秀博客 并不建议初学者看我的博客,因为我也不是很了解FFT的具体原理 一.概述 两个多项式相乘,不用\(N^2\),通过\ ...
- FFT&NTT总结
FFT&NTT总结 一些概念 \(DFT:\)离散傅里叶变换\(\rightarrow O(n^2)\)计算多项式卷积 \(FFT:\)快速傅里叶变换\(\rightarrow O(nlogn ...
- 快速构造FFT/NTT
@(学习笔记)[FFT, NTT] 问题概述 给出两个次数为\(n\)的多项式\(A\)和\(B\), 要求在\(O(n \log n)\)内求出它们的卷积, 即对于结果\(C\)的每一项, 都有\[ ...
- FFT/NTT模板 既 HDU1402 A * B Problem Plus
@(学习笔记)[FFT, NTT] Problem Description Calculate A * B. Input Each line will contain two integers A a ...
- FFT/NTT基础题总结
在学各种数各种反演之前把以前做的$FFT$/$NTT$的题整理一遍 还请数论$dalao$口下留情 T1快速傅立叶之二 题目中要求求出 $c_k=\sum\limits_{i=k}^{n-1}a_i* ...
- $FFT/NTT/FWT$题单&简要题解
打算写一个多项式总结. 虽然自己菜得太真实了. 好像四级标题太小了,下次写博客的时候再考虑一下. 模板 \(FFT\)模板 #include <iostream> #include < ...
- FFT&NTT数学解释
FFT和NTT真是噩梦呢 既然被FFT和NTT坑够了,坑一下其他的人也未尝不可呢 前置知识 多项式基础知识 矩阵基础知识(之后会一直用矩阵表达) FFT:复数基础知识 NTT:模运算基础知识 单位根介 ...
随机推荐
- 25个最佳的 WordPress Gallery 画廊插件
WordPress 画廊插件最适合用于作品展示网站,特别对于那些想以一个奇特的,现代的方式展示他们作品的摄影师.如果你想为你安装 WordPress Gallery 插件,那么下面的是你想要的. 本文 ...
- Javascript实现的2048
HTML代码如下 <!DOCTYPE html> <html> <head> <title></title> <meta charse ...
- iOS常用第三方库
1.AFNetworking 轻量级的通讯类库,使用非常简单. 下载地址:https://github.com/AFNetworking/AFNetworking 2.FMDB fmdb是一个数据 ...
- 8款超实用JavaScript框架
下面盘点了8款实用的JavaScript框架: 1. Hammer.js Hammer.js是被广泛使用的轻量级JavaScript框架,它提供了常用触摸操作的规范,比如收缩.拖放.双击和删除等等.它 ...
- mysql 时间函数转换
1 NOW() //当前时间 2 SYSDATE() //当前时间 3 CURRENT_TIMESTAMP 4 以'YYYY-MM-DD HH:MM:SS'或YYYYMMDDHHMMSS格式返回当前的 ...
- SQLite Design and Concepts
API 分为两大类 core API. 基本的SQL操作 extension API. 创建自定义的SQL操作. 基本数据结构 需要了解的组成部分有连接.statments.B树.pager. 为了写 ...
- JNI输出log信息
1.修改Android.mk 如生成的库文件是“.so文件”,则在Android.mk中添加如下内容: LOCAL_LDLIBS:=-L$(SYSROOT)/usr/lib -llog 如生成的库文件 ...
- iOS 设备标识
//UUID NSLog(@"-=-=-=-=-=-=-=-==-=-==qqqqqqqqqqqqqqqqqqqqqqq:::::::::::%@", [[NSUUID UU ...
- iOS开发-生成随机数
有时候我们需要在程序中生成随机数,但是在Objective-c中并没有提供相应的函数,好在C中提供了rand().srand().random().arc4random()几个函数.那么怎么使用呢?下 ...
- iOS 学习 - 10下载(4) NSURLSession 会话 篇
NSURLConnection通过全局状态来管理cookies.认证信息等公共资源,这样如果遇到两个连接需要使用不同的资源配置情况时就无法解决了,但是这个问题在NSURLSession中得到了解决.N ...