标签:
题意:给出n根木棒的长度,取三根木棒,求不取相同木棒且能构成三角形的概率;
参考:http://www.cnblogs.com/kuangbin/archive/2013/07/24/3210565.html
思路:FFT的结果的意义为计算卷积;
卷积是指在两个集合中各取一个数,可能出现的各种数值的个数;(用每个集合中各种可能出现数值的个数,求各取一个数各种可能出现数值的个数);
得到取两个数的情况后,排除取相同木棒和顺序取棒的情况;
再枚举三边中的最长边,排除有不小于枚举边的情况;
一定要使用long long;
#include<cstdio> #include<cstring> #include<cmath> #include<algorithm> using namespace std; #define pi acos(-1.0) int len1,len2; long long a[500100],num[500100],sum[500100]; struct Complex{ double r,i; Complex(){}; Complex(double x,double y){ r=x,i=y; } Complex operator +(const Complex &t)const{ return Complex(r+t.r,i+t.i); } Complex operator -(const Complex &t)const{ return Complex(r-t.r,i-t.i); } Complex operator *(const Complex &t)const{ return Complex(r*t.r-i*t.i,r*t.i+i*t.r); } }x1[500100]; void fft(Complex y[],int n,int rev) { for(int i=1,j,k,t;i<n;i++){ for(j=0,k=n>>1,t=i;k;k>>=1,t>>=1) j=j<<1|t&1; if(i<j) swap(y[i],y[j]); } for(int s=2,ds=1;s<=n;ds=s,s<<=1){ Complex wn=Complex(cos(rev*2*pi/s),sin(rev*2*pi/s)),w=Complex(1,0),t; for(int k=0;k<ds;k++,w=w*wn){ for(int i=k;i<n;i+=s){ t=w*y[i+ds]; y[i+ds]=y[i]-t; y[i]=y[i]+t; } } } if(rev==-1) for(int i=0;i<n;i++) y[i].r/=n; } long long temp,ans; int main() { int i,j,k,t,n,m; while(scanf("%d",&t)!=EOF) { while(t--) { memset(num,0,sizeof(num)); memset(sum,0,sizeof(sum)); ans=0; scanf("%d",&n); for(i=0;i<n;i++){ scanf("%d",&a[i]); num[a[i]]++; } sort(a,a+n); len1=a[n-1]; int len=1; while(len<=len1*2) len<<=1; for(i=0;i<=len1;i++) x1[i]=Complex(num[i],0); for(;i<len;i++) x1[i]=Complex(0,0); //扩展 fft(x1,len,1); //DFT for(i=0;i<len;i++) x1[i]=x1[i]*x1[i]; //点乘 fft(x1,len,-1); //IDFT for(i=0;i<len;i++) num[i]=(long long)(x1[i].r+0.5); //结果 len=2*a[n-1]; for(i=0;i<n;i++) num[a[i]*2]--; //两根棒相同 for(i=1;i<=len;i++) num[i]/=2; //不同顺序只取一种 for(i=1;i<=len;i++){ sum[i]=sum[i-1]+num[i]; } for(i=0;i<n;i++) //枚举三边中最长边 { ans+=sum[len]-sum[a[i]]; //两边之和大于第三边 ans-=(long long)(n-i-1)*i; //一大一小 ans-=(n-1); //一边与枚举边相同 ans-=(long long)(n-i-1)*(n-i-2)/2; //两大 } temp=(long long)n*(n-1)*(n-2)/6; //一定要long long printf("%.7f\n",(double)ans/temp); } } return 0; }
标签:
原文地址:http://www.cnblogs.com/dominating/p/4661995.html