首页 > 代码库 > hdu 4609 3-idiots(FFT计数)
hdu 4609 3-idiots(FFT计数)
题目链接:hdu 4609 3-idiots
题意:
给你n条线段。问随机取三个,可以组成三角形的概率。
题解:
FFT搞,具体可看kuangbin菊苣的详细题解:传送门
1 #include<bits/stdc++.h> 2 #define F(i,a,b) for(int i=a;i<=b;++i) 3 using namespace std; 4 5 const double pi=acos(-1.0); 6 //n 必须为 2 的幂。 7 struct comp{ 8 double r,i; 9 comp(double _r=0,double _i=0){r=_r,i=_i;} 10 comp operator+(const comp x){return comp(r+x.r,i+x.i);} 11 comp operator-(const comp x){return comp(r-x.r,i-x.i);} 12 comp operator*(const comp x){return comp(r*x.r-i*x.i,r*x.i+i*x.r);} 13 }; 14 15 void FFT(comp a[],int n,int t){ 16 for(int i=1,j=0;i<n-1;i++) 17 { 18 for(int s=n;j^=s>>=1,~j&s;); 19 if(i<j)swap(a[i],a[j]); 20 } 21 for(int d=0;(1<<d)<n;d++) 22 { 23 int m=1<<d,m2=m<<1; 24 double o=pi/m*t;comp _w(cos(o),sin(o)); 25 for(int i=0;i<n;i+=m2) 26 { 27 comp w(1,0); 28 for(int j=0;j<m;j++) 29 { 30 comp &A=a[i+j+m],&B=a[i+j],t=w*A; 31 A=B-t,B=B+t,w=w*_w; 32 } 33 } 34 } 35 if(t==-1)for(int i=0;i<n;i++)a[i].r/=n; 36 } 37 38 const int N=3e5+7; 39 40 comp x1[N],x2[N]; 41 42 long long sum[N]; 43 int a[N],num[N]; 44 45 int main() 46 { 47 int t,n; 48 scanf("%d",&t); 49 while(t--) 50 { 51 memset(num,0,sizeof(num)); 52 scanf("%d",&n); 53 F(i,0,n-1)scanf("%d",a+i); 54 sort(a,a+n); 55 F(i,0,n-1)num[a[i]]++; 56 int len=1,tmp=a[n-1]+1; 57 while(len<2*tmp)len<<=1; 58 F(i,0,len-1) 59 { 60 if(i<tmp)x1[i]=comp(num[i],0); 61 else x1[i]=comp(0,0); 62 } 63 FFT(x1,len,1); 64 F(i,0,len-1)x1[i]=x1[i]*x1[i]; 65 FFT(x1,len,-1); 66 F(i,0,len-1)sum[i]=(long long)(x1[i].r+0.5); 67 len=2*a[n-1]; 68 F(i,0,n-1)sum[a[i]+a[i]]--; 69 F(i,0,len)sum[i]>>=1; 70 F(i,1,len)sum[i]+=sum[i-1]; 71 long long cnt=0; 72 F(i,0,n-1) 73 { 74 cnt+=sum[len]-sum[a[i]]; 75 cnt-=1ll*(n-1-i)*i; 76 cnt-=(n-1); 77 cnt-=1ll*(n-1-i)*(n-i-2)/2; 78 } 79 printf("%.7f\n",(double)cnt/(1ll*n*(n-1)*(n-2)/6)); 80 } 81 return 0; 82 }
hdu 4609 3-idiots(FFT计数)
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。