生活随笔
收集整理的這篇文章主要介紹了
51nod 1172 Partial Sums V2 卡精度的任意模数FFT
小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
卡精度的任意模數(shù)fft模板題……
這道題隨便寫(xiě)個(gè)表就能看出規(guī)律來(lái)(或者說(shuō)考慮一下實(shí)際意義),反正拿到這題之后,很快就會(huì)發(fā)現(xiàn)他是任意模數(shù)fft模板題.
然后我就去網(wǎng)上抄了一下板子……
我打的是最土的任意模數(shù)fft,就是fft7次的那種……(好像有很多方法的樣子……)
這種任意模數(shù)fft方法見(jiàn)http://blog.csdn.net/l_0_forever_lf/article/details/52886397
這道題的具體做法見(jiàn)http://blog.csdn.net/qq_33229466/article/details/78837522
這種方法的思想就是:
I.既然出題人給出了任意模數(shù)的多項(xiàng)式乘法,那么常規(guī)ntt肯定是不行
II.既然他取模,那數(shù)會(huì)很大,會(huì)炸精,常規(guī)的fft也不行
III.既然直接乘會(huì)炸精,那我們就把數(shù)變小,多跑幾次也沒(méi)關(guān)系
(IV.感覺(jué)加了一維卷積,有種這種方法很妙,可以繼續(xù)擴(kuò)展的感覺(jué),但是很模糊,也說(shuō)不具體)
本著這種思路,我們逆變換的時(shí)候,不能在點(diǎn)值表達(dá)式直接操作,最后一遍回去,因?yàn)檫@樣效果和沒(méi)有在一開(kāi)始把數(shù)縮小一樣,會(huì)炸精.
最后說(shuō)一下這道題的坑點(diǎn):如果你不預(yù)處理復(fù)數(shù),你會(huì)炸精.
好像有的人沒(méi)有預(yù)處理,但是用了long double,就沒(méi)有被卡……
似乎cmath庫(kù)里有標(biāo)準(zhǔn)庫(kù)也有類庫(kù),而且有的函數(shù)兩者并不都具有,但是最坑爹的一點(diǎn)是對(duì)于sin,cos等函數(shù),cmath標(biāo)準(zhǔn)庫(kù)的精度大于cmath類庫(kù)……(這只是我經(jīng)過(guò)親身試驗(yàn)做出的推測(cè))
反正預(yù)處理就沒(méi)有這些破事……
#include <cmath>
#include <cstdio>
#include <cstring>
#include <complex>
#include <algorithm>
typedef long long LL;
typedef double db;
typedef std::complex<db>
cd;
const int N=
200010;
const db Pai=acos((db)-
1);
const int P=
1000000007;
cd a1[N],b1[N],a2[N],b2[N],c1[N],c2[N],c3[N],w1[N],w2[N];
int rev[N],len;
int ai[N],bi[N],ans[N],ni[N];
inline void fft(cd *C,
int opt,cd *
wn){register int i,j,k;cd temp;for(i=
1;i<len;++i)
if(rev[i]>
i)std::swap(C[i],C[rev[i]]);for(k=
2;k<=len;k<<=
1){for(i=
0;i<len;i+=
k){for(j=
0;j<(k>>
1);++
j){temp=C[i+j+(k>>
1)]*wn[len/k*
j];C[i+j+(k>>
1)]=C[i+j]-
temp;C[i+j]+=
temp;}}}if(opt==-
1){db inv=
1./
len;for(i=
0;i<len;++i)C[i]*=
inv;}
}
inline void Mul(
int *a,
int *b,
int *c,
int n){len=
1;while(len<n)len<<=
1;int i,sqr=
sqrt(P);cd temp;for(i=
1;i<len;++i)rev[i]=(rev[i>>
1]>>
1)|((i&
1)?(len>>
1):
0);for(i=
0;i<len;++
i){w1[i]=cd(std::cos(
2.*Pai/len*i),std::sin(
2.*Pai/len*
i));w2[i]=cd(std::cos(-
2.*Pai/len*i),std::sin(-
2.*Pai/len*
i));}for(i=
0;i<len;++
i){a1[i]=ai[i]/sqr,b1[i]=ai[i]%
sqr;a2[i]=bi[i]/sqr,b2[i]=bi[i]%
sqr;}fft(a1,1,w1),fft(b1,
1,w1),fft(a2,
1,w1),fft(b2,
1,w1);for(i=
0;i<len;++
i){c1[i]=a1[i]*
a2[i];c2[i]=a1[i]*b2[i]+a2[i]*
b1[i];c3[i]=b1[i]*
b2[i];}fft(c1,-
1,w2),fft(c2,-
1,w2),fft(c3,-
1,w2);for(i=
0;i<len;++
i)c[i]=((LL)(round(c1[i].real()))%P*sqr%P*sqr%P+(LL)(round(c2[i].real()))%P*sqr%P+(LL)(round(c3[i].real()))%P)%
P;
}
int main(){int n,k,i;scanf("%d%d",&n,&
k);for(i=
0;i<n;++i)scanf(
"%d",&
ai[i]);bi[0]=
1;for(i=
1;i<n;++
i)bi[i]=(LL)bi[i-
1]*(k+i-
1)%P*(i==
1?ni[i]=
1:ni[i]=(-(LL)(P/i)*ni[P%i]%P+P)%P)%
P;Mul(ai,bi,ans,n<<
1);for(i=
0;i<n;++i)printf(
"%d\n",ans[i]);return 0;
} ?
轉(zhuǎn)載于:https://www.cnblogs.com/TSHugh/p/8490076.html
總結(jié)
以上是生活随笔為你收集整理的51nod 1172 Partial Sums V2 卡精度的任意模数FFT的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。