1. 程式人生 > >多項式求逆元模板【NTT/拆係數FFT】

多項式求逆元模板【NTT/拆係數FFT】

在這裡插入圖片描述

在這裡插入圖片描述
在這裡插入圖片描述
板題:

一. 洛谷4238

模998244353,NTT:

#include<cstdio>
#include<algorithm>
#define maxn 400005
#define LL long long
using namespace std;
const int mod = 998244353, G = 3;
LL wn,w;
inline LL ksm(LL a,LL b){
	LL s=1;
	for(;b;b>>=1,a=a*a%mod) if(b&1) s=s*a%mod;
	return s;
}
inline
void change(LL *a,int len) { for(int i=1,j=len/2,k;i<len-1;i++) { if(i<j) swap(a[i],a[j]); for(k=len/2;j>=k;j-=k,k>>=1); j+=k; } } inline void ntt(LL *a,int len,int flg) { change(a,len); for(int i=2;i<=len;i<<=1) { if(flg==1) wn=ksm(G,(mod-1)/i); else wn=ksm(G,mod-
1-(mod-1)/i); for(int j=0;j<len;j+=i) { w=1; for(int k=j;k<j+i/2;k++) { LL u=a[k],v=w*a[k+i/2]%mod; a[k]=(u+v)%mod,a[k+i/2]=(u-v+mod)%mod; w=w*wn%mod; } } } if(flg==-1){ LL ni=ksm(len,mod-2); for(int i=0;i<len;i++) a[i]=a[i]*ni%mod; } } int n,len; LL a[maxn],b[
maxn],tmp[maxn]; inline void poly_inv(int n,LL *a,LL *b) { if(n==1) {b[0]=ksm(a[0],mod-2);return;} poly_inv((n+1)>>1,a,b); len=1;while(len<n+n-1) len<<=1; for(int i=0;i<len;i++) tmp[i]=i<n?a[i]:0; ntt(tmp,len,1),ntt(b,len,1); for(int i=0;i<len;i++) {b[i]=(2-tmp[i]*b[i]%mod)*b[i]%mod;if(b[i]<0) b[i]+=mod;} ntt(b,len,-1); for(int i=n;i<len;i++) b[i]=0; } int main() { scanf("%d",&n); for(int i=0;i<n;i++) scanf("%lld",&a[i]); poly_inv(n,a,b); for(int i=0;i<n;i++) printf("%lld%c",b[i],i==n-1?10:32); }
二. 洛谷4239

模109+7,拆係數FFT(7次fft版本)

// luogu-judger-enable-o2
#include<cstdio>
#include<cmath>
#include<algorithm>
#define maxn 400005
#define LL long long
using namespace std;
const int mod = 1e9+7, M1 = 31623, M2 = 14122;
const double Pi = acos(-1);
struct complex
{
	double r,i;
	complex(double _r=0,double _i=0):r(_r),i(_i){}
	complex operator + (const complex &t)const{return complex(r+t.r,i+t.i);}
	complex operator - (const complex &t)const{return complex(r-t.r,i-t.i);}
	complex operator * (const complex &t)const{return complex(r*t.r-i*t.i,r*t.i+i*t.r);}
	complex conj(){return complex(r,-i);}
}w[20][maxn/2];
inline void change(complex *a,int len)
{
	for(int i=1,j=len/2,k;i<len-1;i++)
	{
		if(i<j) swap(a[i],a[j]);
		for(k=len/2;j>=k;j-=k,k>>=1);
		j+=k;
	}
}
inline void fft(complex *a,int len,int flg)
{
	change(a,len);
	for(int i=2,o=0;i<=len;i<<=1,o++)
		for(int j=0;j<len;j+=i)
			for(int k=j;k<j+i/2;k++)
			{
				complex u=a[k],v=(flg==1?w[o][k-j]:w[o][k-j].conj())*a[k+i/2];
				a[k]=u+v,a[k+i/2]=u-v;
			}
	if(flg==-1) for(int i=0;i<len;i++) a[i].r/=len;
}
inline void MTT(int *a,int *b,int n,int *ret)
{
	static complex A[maxn],B[maxn],C[maxn],D[maxn],rt[3][maxn];
	int len=1;while(len<n+n-1) len<<=1;
	for(int i=0;i<len;i++)
		if(i<n)
		{
			A[i]=a[i]/M1,B[i]=a[i]%M1;
			C[i]=b[i]/M1,D[i]=b[i]%M1;
		}
		else A[i]=B[i]=C[i]=D[i]=0;
	fft(A,len,1),fft(B,len,1),fft(C,len,1),fft(D,len,1);
	for(int i=0;i<len;i++) rt[2][i]=A[i]*C[i],rt[1][i]=A[i]*D[i]+B[i]*C[i],rt[0][i]=B[i]*D[i];
	fft(rt[0],len,-1),fft(rt[1],len,-1),fft(rt[2],len,-1);
	for(int i=0;i<n;i++) ret[i]=((llround(rt[0][i].r)%mod+llround(rt[1][i].r)*M1%mod)%mod+llround(rt[2][i].r)*M2%mod)%mod;
}
inline int ksm(int a,int b){
	int s=1;
	for(;b;b>>=1,a=1ll*a*a%mod) if(b&1) s=1ll*s*a%mod;
	return s;
}
int n,a[maxn],b[maxn],tmp[maxn];
inline void poly_inv(int n,int *a,int *b)
{
	if(n==1) {b[0]=ksm(a[0],mod-2);return;}
	poly_inv((n+1)>>1,a,b);
	MTT(a,b,n,tmp);
	MTT(b,tmp,n,tmp);
	for(int i=0;i<n;i++) b[i]=(2*b[i]%mod-tmp[i]+mod)%mod;
}
int main()
{
	scanf("%d",&n);int len=1;while(len<n+n-1) len<<=1;
	for(int i=2,o=0;i<=len;i<<=1,o++)
		for(int j=0;j<i/2;j++)
			w[o][j]=complex(cos(2*Pi*j/i),sin(2*Pi*j/i));
	for(int i=0;i<n;i++) scanf("%d",&a[i]);
	poly_inv(n,a,b);
	for(int i=0;i<n;i++) printf("%d%c",b[i],i==n-1?10:32);
}

FFT(4次fft版本)
演算法解析可以看這兩篇 \darr (膜拜大佬)
Miskcoo’s Space
Clin233

#include<cstdio>
#include<cmath>
#include<algorithm>
#define maxn 400005
#define LL long long
using namespace std;
const int mod = 1e9+7, M = (1<<15)-1;
const double Pi = acos(-1);
struct complex
{
	double r,i;
	complex(double _r=0,double _i=0):r(_r),i(_i){}
	complex operator + (const complex &t)const{return complex(r+t.r,i+t.i);}
	complex operator - (const complex &t)const{return complex(r-t.r,i-t.i);}
	complex operator * (const complex &t)const{return complex(r*t.r-i*t.i,r*t.i+i*t.r);}
	complex conj(){return complex(r,-i);}
}w[20][maxn/2];
inline void change(complex *a,int len)
{
	for(int i=1,j=len/2,k;i<len-1;i++)
	{
		if(i<j) swap(a
            
           

相關推薦

多項式模板NTT/係數FFT

板題: 一. 洛谷4238: 模998244353,NTT: #include<cstdio> #include<algorithm> #define maxn 400005 #define LL long long using namesp

learning 多項式詳解+模板

n) 意義 詳解 需要 一個 求逆 ont time 前置 概述 多項式求逆元是一個非常重要的知識點,許多多項式操作都需要用到該算法,包括多項式取模,除法,開跟,求ln,求exp,快速冪。用快速傅裏葉變換和倍增法可以在$O(n log n)$的時間復雜度下求出一個$n$次

BZOJ 3456: 城市規劃 與 算法介紹(多項式 , dp)

間接 zoj 3456 ini 不難 har 大小 #define form lock 題面 : 求有 \(n\) 個點的無向有標號連通圖個數 . \((1 \le n \le 1.3 * 10^5)\) 題解 : 首先考慮 dp ... 直接算可行的方案數 ,

hdu 1576 A/B 模板

一些基本概念: 乘法逆元,是指數學領域群G中任意一個元素a,都在G中有唯一的逆元a‘,具有性質a×a'=a'×a=e,其中e為該群的單位元。 用[a]n代表x%n=a.的所有滿足條件的x所組成的集合,其中a為集合中最小非負整數,用最小的非負整數來代表整個集合,即[a]n

exgcd模板

求x在模為mod時的逆元: exgcd(x,mod,x,y) 求出後,第三個引數就是逆元。 mod可以不為質數 template <class T> T exgcd(T a, T b, T

[51nod 1258] [伯努利數] [多項式] [任意模數NTT] 序列求和 V4

上次做一套模擬賽的時候,其中需要求自然數k次冪和,然後我只會n^2的…我記得n^2有20分,nlogn求可以爆到90分…… ——鏼鏼鏼2015年國家集訓隊論文 大概就這樣多項式求個逆,求出生成函式就可以了 這樣是O(nlogn),但這道題模數不是滿

洛谷P4238 模板多項式NTT

tdi stdout style show include main -a 沒有 如果 傳送門 學習了一下大佬的->這裏 已知多項式$A(x)$,若存在$A(x)B(x)\equiv 1\pmod{x^n}$ 則稱$B(x)$為$A(x)$在模$x^n$下

Luogu5205 模板多項式開根(NTT+多項式

get def ostream open clas lld https 數組 %d   https://www.cnblogs.com/HocRiser/p/8207295.html 安利!   寫NTT把i<<=1寫成了i<<=2,又調了一年。發現

luoguP4512 模板多項式除法 NTT+多項式+多項式除法

swa define space wap mod inpu eve urn -- Code: #include<bits/stdc++.h> #define maxn 300000 #define ll long long #define MOD

BZOJ4555: [Tjoi2016&Heoi2016]求和 排列組合+多項式 或 斯特林數+NTT

oid int lan ret 多項式 algo com 題意 orm 【題意】給定n,求Σi=0~nΣj=1~i s(i,j)*2^j*j!,n<=10^5。 【算法】生成函數+排列組合+多項式求逆 【題解】參考: [BZOJ4555][Tjoi2016&H

bzoj3456城市規劃 容斥原理+NTT+多項式

方案 所在 scanf 整理 輸入 eof 輸出 std define 題目描述 求出n個點的簡單(無重邊無自環)無向連通圖數目mod 1004535809(479 * 2 ^ 21 + 1). 輸入 僅一行一個整數n(<=130000) 輸出 僅一行一個整

模板線性(洛谷P3367)

Description   給定\(n\),\(p\)求\(1~n\)中所有整數在模\(p\)意義下的乘法逆元。 Input   一行\(n\),\(p\) Output   \(n\)行,第\(i\)行表示\(i\)在模\(p\)意義下的逆元。 Solution #include<c

模板分治FFT -cdq分治/多項式

傳送門:luogu【模板】分治 FFT 題意 給定長度為 n − 1

洛谷 4238 模板多項式

題目:https://www.luogu.org/problemnew/show/P4238 方法:https://www.cnblogs.com/TimelyRain/p/10010233.html    https://www.cnblogs.com/xiefengze1/p/9107752.html

洛谷 4721 模板分治 FFT——分治FFT / 多項式

題目:https://www.luogu.org/problemnew/show/P4721 分治FFT:https://www.cnblogs.com/bztMinamoto/p/9749557.html      https://blog.csdn.net/VictoryCzt/article/det

BZOJ3625CF438E小朋友和二叉樹(生成函式,多項式多項式開根,NTT

Description 我們的小朋友很喜歡電腦科學,而且尤其喜歡二叉樹。 考慮一個含有n個互異正整數的序列c[1],c[2],...,c[n]。如果一棵帶點權的有根二叉樹滿足其所有頂點的權值都在集合{c[1],c[2],...,c[n]}中,我們的小朋友就會將其稱作神犇的。

BZOJ3625CF438E小朋友和二叉樹 NTT 生成函式 多項式開根 多項式

題目大意   考慮一個含有n個互異正整數的序列c1,c2,…,cn。如果一棵帶點權的有根二叉樹滿足其所有頂點的權值都在集合{c1,c2,…,cn}中,我們的小朋友就會將其稱作神犇的。並且他認為,一棵帶點權的樹的權值,是其所有頂點權值的總和。   給出一個整數

bzoj3625CF438E/round250E小朋友和二叉樹FFT/NTT多項式多項式開根

題目連結 題解:我們設f[i]表示權值為i的二叉樹的數目,g[i]為i這個值是否在C集合中出現。則很容易得到f[x]=∑xi−1g[i]∑x−ij=0f[j]f[x−i−j]f[x]=∑i−1xg[i]∑j=0x−if[j]f[x−i−j],且f[0]=1f[

2018.12.30 洛谷P4238 模板多項式

傳送門 多項式求逆模板題。 簡單講講? 多項式求逆 定義: 對於一個多項式 A (

BZOJ3625codeforces438E小朋友和二叉樹 生成函數+多項式+多項式開根

== reverse turn chang 一個 函數 span 化簡 amp 首先,我們構造一個函數$G(x)$,若存在$k∈C$,則$[x^k]G(x)=1$。 不妨設$F(x)$為最終答案的生成函數,則$[x^n]F(x)$即為權值為$n$的神犇二叉樹個數