Test instructions: Gives n a positive integer (array a). Randomly select three numbers at a time. What is the probability that these three numbers will make a triangle?
First, we use a similar bucket count method to make two arrays, a, a, store a few sides of each length, and then the two array convolution.
After the convolution, this represents the 2 edge can constitute a set of edge length, note, because the convolution may be the two same sides added, so the last to find out the array must be subtracted from this repeating part, and then the first calculation of x after the Y is equivalent to the first count y after x, so divide by two.
Then, for the third side A[i], let's consider this: make it the largest of the three edges!
So before the convolution out of the two sides and will certainly be larger than this edge, so every time count: Ans+=sum[mx]-sum[a[i];
Then subtract the repeating part:
(1) One selected I back, one selected I front (minus (i-1) * (n-i))
(2) One selected I, the other random (minus n-1)
(3) Two are all behind I (minus C (n-i,2));
A very interesting topic!
1#include <algorithm>2#include <cstdio>3#include <cmath>4#include <cstring>5#include <iostream>6#include <complex>7 #defineN 3000058 #definell Long Long9typedef std::complex<Double>cd;Ten inta[400005]; Onell c[400005],sum[400005],a[400005],b[400005]; A intN,mxnum; - intBitrev (intTintN) { - intres=0; the for(intI=0; i<n;i++) res|= (t>> (n-i-1)) &1) <<i;//The brackets need to be extra - returnRes; - } - voidFFT (CD *a,intNintrev) { + intlen=1<<N; - StaticCD Y[n];DoublePi=acos (-1); + for(intI=0; i<len;i++) y[i]=A[bitrev (i,n)]; A for(intD=1;d <len;d<<=1){ atCD WN (exp (CD (0, pi*rev/( D) )); - for(intk=0; k<len;k+=2*d) { -cd W (1,0); - for(inti=k;i<k+d;i++,w*=WN) { -CD u=y[i],v=w*y[i+d]; -y[i]=u+v; iny[i+d]=u-v; - } to } + } - if(rev==-1) the for(intI=0; i<len;i++) y[i]/=Len; * for(intI=0; i<len;i++) a[i]=Y[i]; $ }Panax Notoginseng voidMul (ll *a,intLa,ll *b,intLb,ll *c,int&LC) { - intlen=1, n=0; the StaticCD T1[n],t2[n]; + for(; len<la*2|| len<lb*2; len<<=1, n++); A for(intI=0; i<la;i++) T1[I]=CD (A[i],0); the for(intI=0; i<lb;i++) T2[I]=CD (B[i],0); + for(inti=la;i<len;i++) T1[I]=CD (0,0); - for(inti=lb;i<len;i++) T2[I]=CD (0,0); $FFT (T1,n,1); FFT (T2,n,1); $ for(intI=0; i<len;i++) t1[i]*=T2[i]; -FFT (t1,n,-1); - for(intI=0; i<len;i++) c[i]= (Long Long) (T1[i].real () +0.5); theLc=Len; - }Wuyi intMain () { the intT; -scanf"%d",&T); Wu while(t--){ -scanf"%d",&n); About for(intI=1; i<=n;i++) scanf ("%d",&a[i]); $mxnum=0; - for(intI=1; i<=n;i++) mxnum=Std::max (Mxnum,a[i]); - for(intI=1; i<=n;i++) a[a[i]]++,b[a[i]]++; - intLC; AMul (a,mxnum+1, b,mxnum+1, C,LC); + for(intI=1; i<=n;i++) c[a[i]*2]--; the for(intI=1; i<=mxnum*2; i++) c[i]/=2; -sum[0]=0; $ for(intI=1; i<=mxnum*2; i++) thesum[i]=sum[i-1]+C[i]; theStd::sort (A +1, A +1+n); thell ans=0; the for(intI=1; i<=n;i++){ -ans+=sum[mxnum*2]-Sum[a[i]]; inans-= (LL) n-1; theans-= (LL) (I-1) * (ni); theans-= (LL) (n-i) * (n-i-1)/2; About } thell sum= (ll) (n) * (n1) * (n2)/6; theprintf"%.7f\n",(Double)1.0*((Double) (ANS))/((Double) ( sum)); the for(intI=0; i<=mxnum;i++) a[i]=b[i]=sum[i]=c[i]=0; + } -}
HDU 4609 3-idiots (FFT)