一点吐槽:我看网上很多分析,都是在分析这个题的时候,讲了半天的FFT,其实我感觉更多的把FFT当工具用就好了
分析:这个题如果数据小,统计两个相加为 x 的个数这一步骤(这个步骤其实就是求卷积啊),完全可以母函数,无奈数据很大,就用FFT了
然后难点在于最后的统计,要减去自身,两个都大的,一大一小,包含自身,这是用到了容斥,再做相似的题的时候,应该多看看这方面
注:再次高度仰慕kuangbin神,这是我FFT的第二题,也是第二次用kuangbin FFT模板
#include <stdio.h> #include <iostream> #include <algorithm> #include <string.h> #include <vector> #include <math.h> #include <map> using namespace std; typedef long long LL; const int INF=0x3f3f3f3f; const int N=4e5+5; const double pi = acos(-1.0); struct complex{ double r,i; complex(double R=0,double I=0){ r=R;i=I; } complex operator+(const complex &a)const{ return complex(r+a.r,i+a.i); } complex operator-(const complex &a)const{ return complex(r-a.r,i-a.i); } complex operator*(const complex &a)const{ return complex(r*a.r-i*a.i,r*a.i+i*a.r); } }; void change(complex x[],int len){ int i,j,k; for(i=1,j=len/2;i<len-1;++i){ if(i<j)swap(x[i],x[j]); k=len/2; while(j>=k){j-=k;k>>=1;} if(j<k)j+=k; } } void fft(complex x[],int len,int on){ change(x,len); for(int i=2;i<=len;i<<=1){ complex wn(cos(-on*2*pi/i),sin(-on*2*pi/i)); for(int j=0;j<len;j+=i){ complex w(1,0); for(int k=j;k<j+i/2;++k){ complex u = x[k]; complex t = w*x[k+i/2]; x[k]=u+t; x[k+i/2]=u-t; w=w*wn; } } } if(on==-1)for(int i=0;i<len;++i)x[i].r/=len; } complex x[N]; int a[N>>1]; LL num[N],sum[N]; int main(){ int T,n; scanf("%d",&T); while(T--){ scanf("%d",&n); memset(num,0,sizeof(num)); for(int i=0;i<n;++i){scanf("%d",&a[i]);++num[a[i]];} sort(a,a+n); int len1 = a[n-1] + 1,len = 1; while(len<2*len1)len<<=1; for(int i=0;i<len1;++i)x[i]=complex(num[i],0); for(int i=len1;i<len;++i)x[i]=complex(0,0); fft(x,len,1); for(int i=0;i<len;++i)x[i]=x[i]*x[i]; fft(x,len,-1); for(int i=0;i<len;++i) num[i]=(long long)(x[i].r+0.5); len=2*a[n-1]; for(int i=0;i<n;++i)--num[a[i]+a[i]]; for(int i=1;i<=len;++i)num[i]>>=1; for(int i=1;i<=len;++i)sum[i]=sum[i-1]+num[i]; LL cnt=0; for(int i=0;i<n;++i){ cnt+=sum[len]-sum[a[i]]; cnt-=1ll*(n-1-i)*i; cnt-=(n-1); cnt-=1ll*(n-1-i)*(n-i-2)/2; } LL tot=1ll*n*(n-1)*(n-2)/6; printf("%.7f ",1.0*cnt/tot); } return 0; }