Easy Multiplication 快速傅里叶变换
生活随笔
收集整理的這篇文章主要介紹了
Easy Multiplication 快速傅里叶变换
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
Easy Multiplication
時間限制:?1 Sec??內存限制:?128 MB
題目描述
乘法就是加法的連續運算,同一個數若干次連加,其運算結果稱為積
給出兩個n位10進制整數x和y,你需要計算x*y。?
輸入
第一行一個正整數n(n<=200000)。 第二行描述一個位數為n的正整數x。 第三行描述一個位數為n的正整數y。?
輸出
輸出一行,即x*y的結果。?
樣例輸入
5 12345 78945樣例輸出
974576025分析:
首先n的范圍是2*10^5,long long int是沒有辦法計算的,考慮大數乘法
FFT模板題,直接進行高精度乘法是O(n^2)的,于是我們采用FFT來O(nlogn)實現:?
1.我們把乘數的每一位看作多項式的系數,得到多項式A(x)(因為高精度乘法的本質就是多項式乘法)
2.首先求出,其中k∈[0,n?1],是n次單位復根。?
由于n次單位復根的一些奇妙性質:?
相消引理?
折半引理?
我們可以采用分治O(nlogn)的時間求出這nn項的值,但是遞歸實現常數較大,我們采用蝴蝶算法來迭代實現。?
如圖,把原來順次排列的數列變成葉子中的順序就可以迭代了~?
(葉子中的順序就是原序列的二進制逆序)
暴力算法
#include<bits/stdc++.h> using namespace std; int ans[200000*2+20]; char f[200000],g[200000]; int main() {int n;while(~scanf("%d",&n)){fill(ans,ans+n*2+2,0);fill(f,f+(n+2),NULL);fill(g,g+(n+2),NULL);scanf("%s",f);scanf("%s",g);for(int i=1;i<=n;i++){for(int j=1;j<=n;j++){ans[i+j-1]+=(f[n-i]-'0')*(g[n-j]-'0');//printf("%d ",ans[i+j-2]);}} // for(int i=1;i<=n*2;i++) // printf("%d ",ans[i]);for(int i=1;i<=n*2+2;i++){int a;a=ans[i];ans[i]=a%10;ans[i+1]+=a/10;} // for(int i=1;i<=n*2;i++) // printf("%d\n",ans[i]);int s=n*2+2;while(s--){if(ans[s-1]!=0){while(s--&&s>0)printf("%d",ans[s]);printf("\n");break;}} }return 0; }?
與50位技術專家面對面20年技術見證,附贈技術全景圖總結
以上是生活随笔為你收集整理的Easy Multiplication 快速傅里叶变换的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: codeforces 528D. Fuz
- 下一篇: BZOJ2131免费的馅饼 DP+树状