日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪(fǎng)問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

分治FFT

發(fā)布時(shí)間:2024/4/11 编程问答 42 豆豆
生活随笔 收集整理的這篇文章主要介紹了 分治FFT 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

前言

好像是一個(gè)不是很煩的算法
然后和分治套NTT不同

題目

模板題
已知gig_igi?
求每個(gè)fif_ifi?
fi=∑j=1ifi?jgjf_i=\sum_{j=1}^if_{i?j}g_jfi?=j=1i?fi?j?gj?

一般解法

直接求是Θ(n2)\Theta(n^2)Θ(n2)
用FFT直接求是Θ(n2logn)\Theta(n^2logn)Θ(n2logn)
不是很優(yōu)
考慮分治
對(duì)所有位置建立二叉樹(shù)
考慮其的后序遍歷
訪(fǎng)問(wèn)到每個(gè)節(jié)點(diǎn)時(shí),若其是其父親的左兒子,那么對(duì)父親的右兒子進(jìn)行貢獻(xiàn)
直接FFT轉(zhuǎn)移即可
共有lognlognlogn層,每層長(zhǎng)度為nnn,FFT的復(fù)雜度有一個(gè)logloglog
總復(fù)雜度Θ(nlog2n)\Theta(nlog^2n)Θ(nlog2n)

代碼

#include<cstdio> #include<cstring> #include<cctype> namespace fast_IO {const int IN_LEN=10000000,OUT_LEN=10000000;char ibuf[IN_LEN],obuf[OUT_LEN],*ih=ibuf+IN_LEN,*oh=obuf,*lastin=ibuf+IN_LEN,*lastout=obuf+OUT_LEN-1;inline char getchar_(){return (ih==lastin)&&(lastin=(ih=ibuf)+fread(ibuf,1,IN_LEN,stdin),ih==lastin)?EOF:*ih++;}inline void putchar_(const char x){if(oh==lastout)fwrite(obuf,1,oh-obuf,stdout),oh=obuf;*oh++=x;}inline void flush(){fwrite(obuf,1,oh-obuf,stdout);} } using namespace fast_IO; #define getchar() getchar_() #define putchar(x) putchar_((x)) #define rg register typedef long long LL; template <typename T> inline T max(const T a,const T b){return a>b?a:b;} template <typename T> inline T min(const T a,const T b){return a<b?a:b;} template <typename T> inline void mind(T&a,const T b){a=a<b?a:b;} template <typename T> inline void maxd(T&a,const T b){a=a>b?a:b;} template <typename T> inline T abs(const T a){return a>0?a:-a;} template <typename T> inline void swap(T&a,T&b){T c=a;a=b;b=c;} template <typename T> inline T gcd(const T a,const T b){if(!b)return a;return gcd(b,a%b);} template <typename T> inline T lcm(const T a,const T b){return a/gcd(a,b)*b;} template <typename T> inline T square(const T x){return x*x;}; template <typename T> inline void read(T&x) {char cu=getchar();x=0;bool fla=0;while(!isdigit(cu)){if(cu=='-')fla=1;cu=getchar();}while(isdigit(cu))x=x*10+cu-'0',cu=getchar();if(fla)x=-x; } template <typename T> inline void printe(const T x) {if(x>=10)printe(x/10);putchar(x%10+'0'); } template <typename T> inline void print(const T x) {if(x<0)putchar('-'),printe(-x); else printe(x); } const LL mod=998244353,maxn=262146; inline int Md(const int x){return x>=mod?x-mod:x;} inline LL pow(LL x,LL y) {rg LL res=1;for(;y;y>>=1,x=x*x%mod)if(y&1)res=res*x%mod;return res; } int n,f[maxn],g[maxn]; int lenth,Reverse[maxn]; int W[maxn],F[maxn]; inline void init(const int x) {rg int tim=0;lenth=1;while(lenth<x)lenth<<=1,tim++;for(rg int i=0;i<lenth;i++)Reverse[i]=(Reverse[i>>1]>>1)|((i&1)<<(tim-1)); } inline void NTT(int*A,const int fla) {for(rg int i=0;i<lenth;i++)if(i<Reverse[i])swap(A[i],A[Reverse[i]]);for(rg int i=1;i<lenth;i<<=1){const int w=fla==-1?F[i]:W[i];for(rg int j=0;j<lenth;j+=(i<<1)){int K=1;for(rg int k=0;k<i;k++,K=(LL)K*w%mod){const int x=A[j+k],y=(LL)A[j+k+i]*K%mod;A[j+k]=Md(x+y);A[j+k+i]=Md(mod+x-y);}}}if(fla==-1){const int inv=pow(lenth,mod-2);for(rg int i=0;i<lenth;i++)A[i]=(LL)A[i]*inv%mod;} } int A[maxn],B[maxn]; void calc(const int ll,const int rr,const bool sign) {if(ll+1!=rr){const int mid=(ll+rr)>>1; calc(ll,mid,1);calc(mid,rr,0);}if(sign){const int Lth=rr-ll,R=rr+Lth;init(Lth<<1);memcpy(A,f+ll,sizeof(int)*Lth);memset(A+Lth,0,sizeof(int)*Lth);memcpy(B,g,sizeof(int)*(Lth<<1));NTT(A,1),NTT(B,1);for(rg int i=0;i<lenth;i++)A[i]=(LL)A[i]*B[i]%mod;NTT(A,-1);for(rg int i=rr;i<R;i++)f[i]=Md(f[i]+A[Lth+i-rr]);} } int main() {read(n),n--;init(n);for(rg int i=1;i<=n;i++)read(g[i]);for(rg int i=1;i<262144;i<<=1){W[i]=pow(3,(mod-1)/i/2);F[i]=pow(W[i],mod-2);}f[0]=1;calc(0,lenth,0);for(rg int i=0;i<=n;i++)print(f[i]),putchar(' ');return flush(),0; }

多項(xiàng)式求逆解法

我們觀察式子:
fi=∑j=1ifi?jgjf_i=\sum_{j=1}^if_{i?j}g_jfi?=j=1i?fi?j?gj?
我們可以換個(gè)寫(xiě)法(f0f_0f0?即常數(shù)項(xiàng))
f(x)?g(x)+f0=f(x)(modxn)f(x)*g(x)+f_0=f(x)\pmod {x^n}f(x)?g(x)+f0?=f(x)(modxn)
然后移項(xiàng)
f(x)=f0(1?g(x))?1(modxn)f(x)=f_0(1-g(x))^{-1}\pmod {x^n}f(x)=f0?(1?g(x))?1(modxn)
多項(xiàng)式求逆即可
復(fù)雜度O(nlogn)\mathcal O(nlogn)O(nlogn),代碼就不貼了

總結(jié)

好用&清真

總結(jié)

以上是生活随笔為你收集整理的分治FFT的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。