hdu 4609 卷積的應用 FFT

2021-07-03 11:51:53 字數 2826 閱讀 1172

思路是kuangbin大神部落格裡淘來的

其實題目是給了n條線段。問隨機取三個,可以組成三角形的概率。

其實就是要求n條線段,選3條組成三角形的選法有多少種。

首先題目給了a陣列,

如樣例一:

41 3 3 4

把這個陣列轉化成num陣列,num[i]表示長度為i的有num[i]條。

樣例一就是

num =

代表長度0的有0根,長度為1的有1根,長度為2的有0根,長度為3的有兩根,長度為4的有1根。

使用fft解決的問題就是num陣列和num陣列卷積。

num陣列和num陣列卷積的解決,其實就是從取乙個數,從再取乙個數,他們的和每個值各有多少個

例如* 卷積的結果應該是

長度為n的陣列和長度為m的陣列卷積,結果是長度為n+m-1的陣列。

* 卷積的結果應該是。

這個結果的意義如下:

從取乙個數,從再取乙個數

取兩個數和為 2 的取法是一種:1+1

和為 4 的取法有四種:1+3, 1+3  ,3+1 ,3+1

和為 5 的取法有兩種:1+4 ,4+1;

和為 6的取法有四種:3+3,3+3,3+3,3+3,3+3

和為 7 的取法有四種: 3+4,3+4,4+3,4+3

和為 8 的取法有 一種:4+4

利用fft可以快速求取迴圈卷積,具體求解過程不解釋了,就是dft和fft的基本理論了。

總之fft就是快速求到了num和num卷積的結果。只要長度滿足》=n+m+1.那麼就可以用迴圈卷積得到線性卷積了。

弄完fft得到乙個num陣列,這個陣列的含義在上面解釋過了。

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);

這裡**中的num陣列就是卷積後的結果,表示兩兩組合。

但是題目中本身和本身組合是不行的,所有把取同乙個的組合的情況刪掉。

//

減掉取兩個相同的組合

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

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

還有,這個問題求組合,所以第乙個選t1,第二個選t2,和第乙個選t2,第二個選t1,我們認為是一樣的。

所有num陣列整體除於2

//

選擇的無序,除以2

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

然後對num陣列求字首和

sum[0] = 0

;

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

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

之後就開始o(n)找可以形成三角形的組合了。

a陣列從小到大排好序。

對於a[i].  我們假設a[i]是形成的三角形中最長的。這樣就是在其餘中選擇兩個和》a[i],而且長度不能大於a[i]的。(注意這裡所謂的大於小於,不是 說長度的大於小於,其實是排好序以後的,位置關係,這樣就可以不用管長度相等的情況,排在a[i]前的就是小於的,後面的就是大於的)。

根據前面求得的結果。

長度和大於a[i]的取兩個的取法是sum[len]-sum[a[i]].

但是這裡面有不符合的。

乙個是包含了取一大一小的

cnt -= (long long)(n-1-i)*i;

乙個是包含了取乙個本身i,然後取其它的

cnt -= (n-1);

還有就是取兩個都大於的了

cnt -= (long long)(n-1-i)*(n-i-2)/2;

這樣把i從0~n-1累加,就答案了。

long

long cnt = 0

;

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

#include #include #include #include #includeusing namespace std;

const int n = 500005;

const double pi = acos(-1.0);

int n;

struct virt

virt operator + (const virt &x)

virt operator - (const virt &x)

virt operator * (const virt &x)

};//雷德演算法--倒位序

void rader(virt f, int len)

if(j < k) j += k;

}}//fft實現

void fft(virt f, int len, int on)

sort(a,a+n);

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

len = 1;

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

for(int i=0; i

1 1卷積核的作用

如何理解跨通道的資訊互動和整合呢?首先還得從三維卷積的計算開始。如圖所示,藍色部分是乙個7 7 n 維數 的feature map,黃色塊為3 3 3的卷積核,將卷積核對應到藍色特徵中可以得到乙個紅色陰影區域,舉個具體的例子 假設卷積核所有的引數都為1。那麼紅色部分的數值 1 1 4 1 3 1 2...

卷積神經網路中的1 1卷積

我們都知道,卷積核的作用在於特徵的抽取,越是大的卷積核尺寸就意味著更大的感受野,當然隨之而來的是更多的引數。早在1998年,lecun大神發布的letnet 5模型中就會出,影象空域內具有區域性相關性,卷積的過程是對區域性相關性的一種抽取。但是在學習卷積神經網路的過程中,我們常常會看到一股清流般的存...

MATLAB conv2卷積的實現

matlab conv2卷積的實現 這裡給出一種最原始的實現方案。這種實現對於資料矩陣大小為1000x1000,卷積核矩陣大小為20x20,在我的機器上需要大約1秒鐘的時間,而matlab採用的mkl庫最快只需要將近0.1s的時間。下面的 用到了自己目前開發的fastiv中的一些函式介面。具體 如下...