ntt

NTT 模板

醉酒当歌 提交于 2019-12-02 20:34:17
其实和 $FFT$ 就是一个模子里刻出来的一样, $FFT$ 的优化是基于它的单位根 而 $NTT$ 的模数通常有一个原根, 和 $FFT$ 的单位根有类似的性质 还是存个模板 模板题 #include <iostream> #include <stdio.h> #include <stdlib.h> #include <string.h> #define MAXN 3000010 using namespace std; typedef long long LL; const int mod=998244353; const int g=3; int n,m,rev[MAXN],bit=0,len=1; LL a[MAXN],b[MAXN]; int read(){ int x=0,f=1;char c=getchar(); while(c<'0'||c>'9') {if(c=='-')f=-1;c=getchar();} while(c>='0'&&c<='9') {x=x*10+c-'0';c=getchar();} return x*f; } LL qpow(LL x,LL k){ LL res=1; while(k){ if(k&1) res=res*x%mod; x=x*x%mod; k>>=1; } return res; } void NTT(LL *a,int

Educational Codeforces Round 75 (Rated for Div. 2)

风格不统一 提交于 2019-12-02 11:21:26
(体验到了胡出一道题但是写锅的绝望呢) A: 送分题。 #include<bits/stdc++.h> #define maxn 100005 #define maxm 500005 #define inf 0x7fffffff #define ll long long using namespace std; bool may[30]; char str[maxn]; inline int read(){ int x=0,f=1; char c=getchar(); for(;!isdigit(c);c=getchar()) if(c=='-') f=-1; for(;isdigit(c);c=getchar()) x=x*10+c-'0'; return x*f; } int main(){ int T=read(); while(T--){ scanf("%s",str+1); int n=strlen(str+1); memset(may,0,sizeof(may)); for(int i=1;i<=n;){ int j=i; while(str[j]==str[j+1]) j++; if((j-i+1)%2) may[str[i]-'a']=1; i=j+1; } for(int i=0;i<26;i++) if(may[i]) printf("%c",(char)(i+

多项式模板整理

馋奶兔 提交于 2019-12-01 11:50:54
多项式模板整理 多项式乘法 1 inline void NTT(int *A,int tag) 2 { 3 FOR(i,0,lim-1) if (i<rev[i]) swap(A[i],A[rev[i]]); 4 for (register int mid=1;mid<lim;mid<<=1) 5 { 6 int Wn=qpow(g,(mod-1)/(mid<<1)); 7 if (tag==-1) Wn=qpow(Wn,mod-2); 8 for (register int Len=mid<<1,l=0;l<lim;l+=Len) 9 { 10 int w=1; 11 for (register int k=0;k<mid;k++,w=1LL*w*Wn%mod) 12 { 13 int x=A[l+k],y=1LL*w*A[l+mid+k]%mod; 14 A[l+k]=(1LL*x+y)%mod; 15 A[l+k+mid]=(1LL*x-y+mod)%mod; 16 } 17 } 18 } 19 if (tag==-1) 20 { 21 int inv=qpow(lim,mod-2); 22 FOR(i,0,lim-1) A[i]=1LL*A[i]*inv%mod; 23 } 24 return; 25 } View Code 多项式求逆 $$A*B \equiv 1 (

p4841 城市规划

白昼怎懂夜的黑 提交于 2019-12-01 07:40:49
分析 https://www.luogu.org/blog/DRA/solution-p4841 代码(似乎附赠了一个全家桶呢) #pragma GCC optimize(2) #pragma GCC optimize(3) #pragma GCC optimize("Ofast") #pragma GCC optimize("inline") #pragma GCC optimize("-fgcse") #pragma GCC optimize("-fgcse-lm") #pragma GCC optimize("-fipa-sra") #pragma GCC optimize("-ftree-pre") #pragma GCC optimize("-ftree-vrp") #pragma GCC optimize("-fpeephole2") #pragma GCC optimize("-ffast-math") #pragma GCC optimize("-fsched-spec") #pragma GCC optimize("unroll-loops") #pragma GCC optimize("-falign-jumps") #pragma GCC optimize("-falign-loops") #pragma GCC optimize("-falign

hdu 6589

拥有回忆 提交于 2019-11-30 05:13:46
NTT 首先发现操作的交换不影响答案 然后再打表,发现每项是一个组合数 然后NTT处理就行了 #include <bits/stdc++.h> using namespace std; typedef long long ll; const int maxn = 2e6 + 5, P = 998244353; namespace NTT { int power(int x, int t) { int ret = 1; for(; t; t >>= 1, x = 1LL * x * x % P) if(t & 1) ret = 1LL * ret * x % P; return ret; } void NTT(int *a, int len, int f) { int n = 1 << len; for(int i = 0; i < n; ++i) { int t = 0; for(int j = 0; j < len; ++j) if(i >> j & 1) t |= 1 << (len - j - 1); if(i < t) swap(a[i], a[t]); } for(int l = 2; l <= n; l <<= 1) { int m = l >> 1; int w = power(3, f == 1 ? (P - 1) / l : (P - 1) - (P - 1) /

[luogu4389][生成函数][NTT]付公主的背包

情到浓时终转凉″ 提交于 2019-11-29 22:42:14
luogu4389 考虑OGF, a n s = [ x n ] ∏ i = 1 n ( 1 1 − x i ) a i ans=[x^n]\prod_{i=1}^n(\frac{1}{1-x^i})^{a_i} a n s = [ x n ] ∏ i = 1 n ​ ( 1 − x i 1 ​ ) a i ​ ,其中 a i a_i a i ​ 表示大小为 i i i 的物品的个数 看到这种一般想到用exp: ∏ i = 1 n ( 1 1 − x i ) a i \prod_{i=1}^n(\frac{1}{1-x^i})^{a_i} i = 1 ∏ n ​ ( 1 − x i 1 ​ ) a i ​ = e x p ( − ∑ i = 1 n a i l n ( 1 − x i ) ) =exp(-\sum_{i=1}^na_iln(1-x^i)) = e x p ( − i = 1 ∑ n ​ a i ​ l n ( 1 − x i ) ) 求导: = e x p ( − ∑ i = 1 n a i ∑ j ≥ 1 x i j j ) =exp(-\sum_{i=1}^na_i\sum_{j\ge1}\frac{x^{ij}}{j}) = e x p ( − i = 1 ∑ n ​ a i ​ j ≥ 1 ∑ ​ j x i j ​ ) 交换求和顺序: = e x p (

Translation from Complex-FFT to Finite-Field-FFT

泪湿孤枕 提交于 2019-11-28 12:43:37
Good afternoon! I am trying to develop an NTT algorithm based on the naive recursive FFT implementation I already have. Consider the following code ( coefficients ' length, let it be m , is an exact power of two): /// <summary> /// Calculates the result of the recursive Number Theoretic Transform. /// </summary> /// <param name="coefficients"></param> /// <returns></returns> private static BigInteger[] Recursive_NTT_Skeleton( IList<BigInteger> coefficients, IList<BigInteger> rootsOfUnity, int step, int offset) { // Calculate the length of vectors at the current step of recursion. // - int n =

多项式模板

强颜欢笑 提交于 2019-11-28 07:24:53
// 洛谷多项式模板题,整理了自己的数论FFT,NTT的模板。 P3803 【模板】多项式乘法(FFT) #include<cstdio> #include<iostream> #include<complex> #include<cmath> const double pi = acos(-1); // #define cp complex<double> using namespace std; const int maxn = 1500100; struct cp { double x, y; cp(double xx=0, double yy=0):x(xx), y(yy) {} cp operator+(const cp& b) { return cp(x+b.x, y+b.y); } cp operator-(const cp& b) { return cp(x-b.x, y-b.y); } cp operator*(const cp& b) { return cp(x*b.x-y*b.y, x*b.y+y*b.x); } cp operator*=(const cp& b) { double tmpx = x*b.x - y*b.y; y = x*b.y + y*b.x; x = tmpx; return *this; } }; int n, m; cp a[maxn

[生成函数][DFT][NTT] Hdu P6067 Big Integer

会有一股神秘感。 提交于 2019-11-27 13:01:24
题解 代码 1 #include <cstdio> 2 #include <istream> 3 #define ll long long 4 using namespace std; 5 const ll N=200010,mo=786433; 6 int T,n,m,k,x,y,sum,num[N],f[N],len,L,rev[N],v[10][N]; 7 ll a[10][N],inv[mo],fac[N],ny[N],ans[N],p[N],P[N]; 8 char s[N]; 9 ll ksm(ll a,ll b) { ll r=1; for (;b;b>>=1,a=a*a%mo) if (b&1) r=r*a%mo; return r; } 10 void ntt(ll *a,int len,int f) 11 { 12 for (int i=0;i<len;i++) if (rev[i]>i) swap(a[i],a[rev[i]]); 13 for (int i=2;i<=len;i<<=1) 14 { 15 ll r,m=i>>1; 16 if (f==1) r=p[i]; else r=P[i]; 17 for (int j=0;j<len;j+=i) 18 { 19 ll R=1; 20 for (int k=0;k<m;k++,R=R*r%mo) 21 {

任意模数NTT(MTT)

末鹿安然 提交于 2019-11-27 07:45:17
前言 众所周知,NTT有几个经典的模数: 469762049 , 998244353 , 1004535809 469762049,998244353,1004535809 4 6 9 7 6 2 0 4 9 , 9 9 8 2 4 4 3 5 3 , 1 0 0 4 5 3 5 8 0 9 为什么这些模数被称为NTT模数呢?因为他们都是这样一个形式: P = 2 a ∗ X + 1 P=2^a*X+1 P = 2 a ∗ X + 1 为什么要有这样一个条件呢,因为只有这样,才能找到所需的原根 所以对于一般的一个模数 P = 2 a ∗ X + 1 P=2^a*X+1 P = 2 a ∗ X + 1 ,能适用的最大的多项式长度(包括结果)是 2 a 2^a 2 a 有时候, 给出的多项式长度超过限制,我们就不能用裸的NTT了 一般有两种情况: 模数是NTT模数,但是多项式长度略超出限制(比如模数是1004535809,输入多项式长度和>2097152) 模数不是NTT模数,比如模数是1000000007 这个时候任意模数NTT就非常有用了 正文 我们来分析任意模数NTT做法的思路 思路一(P不是很大的时候) 根据分析,我们发现,多项式长度为N、模数为P的时候,多项式乘法的结果每一项的值 0 ≤ x ≤ P 2 N 0\le x\le P^2N 0 ≤ x ≤ P 2 N