Reprint please indicate the source, thank you http://blog.csdn.net/ACM_cxlove? Viewmode = contents by --- cxlove
Question: give n sides and ask the probability that three sides can form a triangle.
Http://acm.hdu.edu.cn/showproblem.php? PID = 1, 4609
The theory of FFT is not very clear for the first time. First, we need to understand convolution.
I just want to saveCodeFor details, refer to the explanation of the kuangbin giant
Http://www.cnblogs.com/kuangbin/archive/2013/07/24/3210565.html
Num [I] indicates the number of edges with the length of I. After a convolution of num and Num, num [I] indicates the number of pairs of the two edges and I.
Then we need to repeat it, and finally we can make O (n) statistics. Pay attention to the de-duplication areas. The blog will be detailed.
# Include <iostream> # include <cstdio> # include <cstring> # include <cmath> # include <algorithm> using namespace STD; // FFT copy from kuangbinconst double Pi = ACOs (-1.0); // complex z = a + B * I struct Complex {double A, B; complex (double _ A = 0.0, double _ B = 0.0): A (_ A), B (_ B) {} complex operator + (const complex & C) const {return complex (A + C. a, B + C. b);} complex operator-(const complex & C) const {return complex (a-c. a, B-c. b);} complex operator * (const complex & C) const {return complex (A * C. a-B * C. b, A * C. B + B * C. a) ;}}; // Len = 2 ^ kvoid change (complex y [], int Len) {for (INT I = 1, j = Len/2; I <len-1; I ++) {if (I <j) Swap (Y [I], Y [J]); int K = Len/2; while (j> = k) {J-= K; k/= 2;} If (j <k) J + = K ;}} // FFT // Len = 2 ^ K // on = 1 DFT on =-1 idftvoid FFT (complex y [], int Len, int on) {change (Y, len); For (int h = 2; H <= Len; H <= 1) {complex Wn (COS (-on * 2 * PI/h ), sin (-on * 2 * PI/H); For (Int J = 0; j <Len; j + = h) {complex W (1, 0 ); for (int K = J; k <j + H/2; k ++) {complex u = Y [k]; complex T = W * Y [K + H/2]; y [k] = u + T; y [K + H/2] = u-t; W = W * wn ;}}if (on =-1) {for (INT I = 0; I <Len; I ++) {Y [I]. a/= Len ;}}const int n = 100005; typedef long ll; int n, a [n]; ll sum [n <2], num [n <2]; complex X1 [n <2]; int main () {# ifndef online_judge freopen ("input.txt", "r", stdin ); # endif int t; scanf ("% d", & T); While (t --) {memset (Num, 0, sizeof (Num )); scanf ("% d", & N); For (INT I = 0; I <n; I ++) {scanf ("% d ", & A [I]); num [A [I] ++;} Sort (A, A + n); int Len = A [n-1] + 1; int L = 1; while (L <Len * 2) L <= 1; for (INT I = 0; I <Len; I ++) {x1 [I] = complex (Num [I], 0) ;}for (INT I = Len; I <L; I ++) {x1 [I] = complex (0, 0);} FFT (x1, L, 1); For (INT I = 0; I <L; I ++) {x1 [I] = x1 [I] * X1 [I];} FFT (x1, L,-1); For (INT I = 0; I <L; I ++) {num [I] = (LL) (x1 [I]. A + 0.5);} l = 2 * A [n-1]; for (INT I = 0; I <n; I ++) {num [A [I] <1] --;} For (INT I = 1; I <= L; I ++) {num [I]/= 2 ;} sum [0] = 0; For (INT I = 1; I <= L; I ++) {sum [I] = sum [I-1] + num [I];} double ans = 0; For (INT I = 0; I <n; I ++) {ans + = sum [l]-sum [A [I]; ANS-= n-1; ANS-= (double) I * (N-1-I ); ans-= (double) (n-I-1) * (N-I-2)/2;} printf ("%. 7f \ n ", ANS * 6.0/N/(n-1.0)/(n-2.0);} return 0 ;}