zoukankan      html  css  js  c++  java
  • HDU 4609 FFT

     题目大意

    给定n条边的边值,求任意取三条边能组成三角形的概率

    这里概率 P = valid/tot

    tot = (n-2)*(n-1)*n/6是没问题的

    valid表示合法的方式

    先考虑,任意两条边组合形成方法的总数

    因为边值在100000的范围内,这里组合用fft计算

    得到最后形成和为 i 的两条边的方法数为 num[i]

    这里计算后要记得减去取两条相同边的情况,还有 取 3,4 和 4,3是一样的,要记得除以2

    最后跑个n的循环,每次将当前边作为排序后(主要是因为有长度相同的边才这么考虑)次序最大的边,然后保证得到的和是两条在它前面的边组成的

    这个计算就需要求个总方法数的前缀和了

    取到所有和大于当前边的方法数,减去由两条比它大的边组成的情况(n-i)*(n-i-1)/2,一个比他大一个比他小组成的(n-i)*(i-1),还有它其余任意一条边组成的(n-1)

      1 #include <cstdio>
      2 #include <cstring>
      3 #include <cmath>
      4 #include <iostream>
      5 #include <algorithm>
      6 using namespace std;
      7 #define N 100005
      8 #define ll long long
      9 const double PI = acos(-1.0);
     10 
     11 int n , a[N] , cnt[N] ;
     12 ll num[N<<2] , sum[N<<2];
     13 
     14 struct complex{
     15     double r , i;
     16     complex(double r=0 , double i=0):r(r),i(i){}
     17     complex operator+(const complex &a) const{
     18         return complex(r+a.r , i+a.i);
     19     }
     20     complex operator-(const complex &a) const{
     21         return complex(r-a.r , i-a.i);
     22     }
     23     complex operator*(const complex &a) const{
     24         return complex(r*a.r-i*a.i , r*a.i+i*a.r);
     25     }
     26 };
     27 
     28 void change(complex y[] , int len)
     29 {
     30     int i,j,k;
     31     for(i=1 , j=len/2 ; i<len-1 ; i++){
     32         if(i<j) swap(y[i],y[j]);
     33         k = len/2;
     34         while(j>=k){
     35             j-=k;
     36             k/=2;
     37         }
     38         if(j<k) j+=k;
     39     }
     40 }
     41 
     42 void fft(complex y[] , int len , int on)
     43 {
     44     change(y , len);
     45     for(int i=2 ; i<=len ; i<<=1){
     46         complex wn(cos(-on*2*PI/i) , sin(-on*2*PI/i));
     47         for(int j=0 ; j<len ; j+=i){
     48             complex w(1,0);
     49             for(int k=j ; k<j+i/2 ; k++){
     50                 complex u = y[k];
     51                 complex t = w*y[k+i/2];
     52                 y[k] = u+t;
     53                 y[k+i/2] = u-t;
     54                 w = w*wn;
     55             }
     56         }
     57     }
     58     if(on==-1)
     59         for(int i=0 ; i<len ; i++)
     60             y[i].r /= len;
     61 
     62 }
     63 complex x[N<<2];
     64 
     65 int main()
     66 {
     67    // freopen("a.in" , "r" , stdin);
     68     int T;
     69     scanf("%d" , &T);
     70     while(T--){
     71         scanf("%d" , &n);
     72         int mx = 0;
     73         memset(cnt , 0 , sizeof(cnt));
     74         for(int i=1 ; i<=n ; i++){
     75             scanf("%d" , &a[i]);
     76             cnt[a[i]]++ , mx=max(mx , a[i]);
     77         }
     78         int len = 1;
     79         while(len<2*(mx+1)) len<<=1;
     80         for(int i=0 ; i<=mx ; i++) x[i] = complex(cnt[i] , 0);
     81         for(int i=mx+1 ; i<len ; i++) x[i] = complex(0 , 0);
     82         fft(x , len , 1);
     83         for(int i=0 ; i<len ; i++)
     84             x[i] = x[i]*x[i];
     85         fft(x , len , -1);
     86         for(int i=0 ; i<len ; i++) num[i] = (ll)(x[i].r+0.5);
     87         for(int i=1 ; i<=n ; i++) num[a[i]+a[i]]--;
     88         for(int i=0 ; i<len ; i++){
     89             num[i]/=2;
     90             if(i) sum[i] = sum[i-1]+num[i];
     91         }
     92         ll ans = 0;
     93         sort(a+1 , a+n+1);
     94         for(int i=1 ; i<=n ; i++){
     95             ll val = sum[len-1]-sum[a[i]];
     96             val = val - (n-1);
     97             val = val - (ll)(n-i)*(i-1);
     98             val = val - (ll)(n-i)*(n-i-1)/2;
     99           //  cout<<i<<" "<<a[i]<<" "<<sum[len-1]-sum[a[i]]<<" "<<val<<endl;
    100             ans = ans+val;
    101         }
    102         printf("%.7f
    " , ans*6.0/((ll)n*(n-1)*(n-2)));
    103     }
    104     return 0;
    105 }
  • 相关阅读:
    HDU 5821 Ball (贪心)
    hdu 5826 physics (物理数学,积分)
    HDU 5831 Rikka with Parenthesis II (贪心)
    HDU 2669 Romantic (扩展欧几里得定理)
    POJ 2442 Sequence
    HDU 3779 Railroad(记忆化搜索)
    博客园首页新随笔联系管理订阅 随笔- 524 文章- 0 评论- 20 hdu-5810 Balls and Boxes(概率期望)
    hdu 5813 Elegant Construction (构造)
    hdu 5818 Joint Stacks (优先队列)
    C#字段和属性
  • 原文地址:https://www.cnblogs.com/CSU3901130321/p/4910831.html
Copyright © 2011-2022 走看看