快速傅利葉

2021-08-05 20:01:22 字數 3531 閱讀 7860

參考 : 

%ae%97

%e6%b3

%95%e5

%ad%a6

%e4%b9

%a0%e7

%ac%94

%e8%ae

%b0/

hdu大整數乘法

#include

#include

#include

#include

#include

using

namespace

std;

const

double pi = acos(-1.0);

//複數結構體

struct

complex

complex

operator +(const

complex &b)

complex

operator -(const

complex &b)

complex

operator *(const

complex &b)

};/*

* 進行fft和ifft前的反轉變換。

* 位置i和 (i二進位制反轉後位置)互換

* len必須去2的冪

*/void change(complex y,int len)

if(j < k) j += k;

}}/*

* 做fft

* len必須為2^k形式,

* on==1時是dft,on==-1時是idft

*/void fft(complex y,int len,int on)}}

if(on == -1)

for(int i = 0;i < len;i++)

y[i].r /= len;

}const

int maxn = 200010;

complex x1[maxn],x2[maxn];

char str1[maxn/2],str2[maxn/2];

int sum[maxn];

int main()

len = len1+len2-1;

while(sum[len] <= 0 && len > 0)len--;

for(int i = len;i >= 0;i--)

printf("%c",sum[i]+'0');

printf("\n");

}return

0;}

hdu4609快速卷積

#include

#include

#include

#include

#include

using

namespace

std;

//快速傅利葉fft:快速卷積 | 求兩組離散序列的卷積,對於給定的序列xi和yi,他們卷積的第r位的值是所有序列xi和序列yi的下標組合為r的兩個數值的乘和

//也就是f(r) = 求和( x(i) * y(r-i) )

//本題給出一組數,求在裡面選擇三個數組成三角形的個數。可以用num陣列記錄其中每個數字出現的次數,下標代表每個數字,之後最num陣列快速卷積,之後去重和去取自身的個數,得到的就是對給定的序列任取兩個數得到他們的和不同數字的個數

//快速卷積:對於給定的兩個個數序列xi和yi(下標i代表乙個數字,數值xi或者yi代表數字i個個數),他們組合成不同的數(指下標i組合成不同的數,比如k= i+j = (i-1) + (j+1) )的個數

//快速傅利葉求卷積:多項式乘法和本題都是快速傅利葉求卷積的型別。對於給定的兩個序列,求乙個序列,他的下標是先前兩個序列下標的組合,他的值是先前兩個序列下標組合的值積和。這樣的序列 就是兩個序列的離散卷積

//求卷積可以應用到多項式乘法和從一組數字中任選兩個數相加看他們能夠組成不同數字的每個數字的個數。如果樸素的演算法是o(n^2)的,但是快速卷積可以變成o(nlogn)

const

double pi = acos(-1.0);

struct

complex

complex

operator +(const

complex &b)

complex

operator -(const

complex &b)

complex

operator *(const

complex &b)

};void change(complex y,int len)

if(j < k)j += k;

}}void fft(complex y,int len,int on)}}

if(on == -1)

for(int i = 0;i < len;i++)

y[i].r /= len;

}const

int maxn = 400040;

complex x1[maxn];

int a[maxn/4];

long

long num[maxn];//100000*100000會超int

long

long sum[maxn];

int main()

sort(a,a+n);

//注意還有0

int len1 = a[n-1]+1;

int len = 1;

while( len < 2*len1 )len <<= 1;

for(int i = 0;i < len1;i++)

x1[i] = complex(num[i],0);

for(int i = len1;i < len;i++)

x1[i] = complex(0,0);

fft(x1,len,1);

for(int i = 0;i < len;i++)

x1[i] = x1[i]*x1[i];

fft(x1,len,-1);

for(int i = 0;i < len;i++)

num[i] = (long

long)(x1[i].r+0.5);

len = 2*a[n-1];

//減掉取兩個相同的組合

for(int i = 0;i < n;i++)

num[a[i]+a[i]]--;

//選擇的無序,除以2

for(int i = 1;i <= len;i++)

sum[0] = 0;

for(int i = 1;i <= len;i++)

sum[i] = sum[i-1]+num[i];

long

long cnt = 0;

for(int i = 0;i < n;i++)

//總數

long

long tot = (long

long)n*(n-1)*(n-2)/6;

printf("%.7lf\n",(double)cnt/tot);

}return

0;}

快速傅利葉(FFT)

快速傅利葉 更加形象的理解傅利葉變換 大概了解之後 從傅利葉級數到傅利葉變換 太大,只能裁剪為兩張 刨根問底的同學 雷德演算法 輸出序列是按自然順序排列的,而輸入序列的順序則是 位元反轉 方式排列的。也就是說,將序號用二進位制表示,然後將二進位制數以相反方向排列,再以這個數作為序號。如011變成11...

FFT快速傅利葉

description 給出兩個n位10進製整數x和y,你需要計算xy。input 第一行乙個正整數n。第二行描述乙個位數為n的正整數x。第三行描述乙個位數為n的正整數y output 輸出一行,即xy的結果。資料範圍 n 60000 乙個整數x a nan 1.a 0x a na a 0 x an...

快速傅利葉演算法(灌水)

係數表示法 a x n 1j 0aj xj點值表示法 x 0,y0 x 1,y1 x n 1,yn 1 n次單位復根,滿足條件wn 1,可得w e2 i k n n次單位複數根滿足一些基本性質 對於多項式a x 計算它在n個n次單位複數根處的值,即可求出其離散傅利葉變換 dft 所以我們求其在n個n...