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

    题意:给出一堆数,问从这些数中取3个能组成三角形的概率?

    sol:其实就是问从这些数里取3个组成三角形有多少种取法

    脑洞大开的解法:用FFT

    设一开始的数是1 3 3 4

    作一个向量x,其中x[i]=边长为i的边的个数

    那么就有x=[0 1 0 2 1 0 0 0 0]

    令y=x,对x和y作DFT,得到dx和dy。令dn=dx*dy,再对dn作IDFT得到n

    那么就得到n=[0 0 1 0 4 2 4 4 1 0 ]

    其中n[i]=在x和y中各选一条边,使得两条边之和为i有几种方案

    这时得到的n并不好,包含了各种重复的方案。还得减一下

    最后得到的n=[0 0 0 0 2 1 1 2 0]

    然后对n做奇怪的操作。。。

    先求前缀和,得到S

    对于a[i].  我们假设a[i]是形成的三角形中最长的。这样就是在其余中选择两个和>a[i],而且长度不能大于a[i]的。(注意这里所谓的大于小于,不是说长度的大于小于,其实是排好序以后的,位置关系,这样就可以不用管长度相等的情况,排在a[i]前的就是小于的,后面的就是大于的)。
    
    根据前面求得的结果。
    长度和大于a[i]的取两个的取法是sum[len]-sum[a[i]].
    
    但是这里面有不符合的。
    
    一个是包含了取一大一小的
    cnt -= (long long)(n-1-i)*i;
    
    一个是包含了取一个本身i,然后取其它的
    cnt -= (n-1);
    
    还有就是取两个都大于的了
    cnt -= (long long)(n-1-i)*(n-i-2)/2;
    View Code

    Code:

      1 #include  <stdio.h>
      2 #include  <string.h>
      3 #include  <iostream>
      4 #include  <algorithm>
      5 #include  <math.h>
      6 using namespace  std;
      7 const double PI = acos(-1.0);
      8 #define LL long long
      9 #define MAXL 524230
     10 #define MAXN 100010
     11 
     12 //复数结构体
     13 struct  Complex
     14 {
     15     double x,y;//实部和虚部  x+yi
     16     Complex(double _x = 0,double _y = 0)
     17     {
     18         x = _x;
     19         y = _y;
     20     }
     21     Complex operator -(const Complex &b)const
     22     {
     23         return  Complex(x-b.x,y-b.y);
     24     }
     25     Complex operator +(const Complex &b)const
     26     {
     27         return  Complex(x+b.x,y+b.y);
     28     }
     29     Complex operator *(const Complex &b)const
     30     {
     31         return  Complex(x*b.x-y*b.y,x*b.y+y*b.x);
     32     }
     33 };
     34 /*
     35 *进行FFT和IFFT前的反转变换。
     36 *位置i和(i二进制反转后位置)互换
     37 * len必须去2的幂
     38 */
     39 void change(Complex y[],int  len)
     40 {
     41     int  i,j,k;
     42     for(i = 1, j = len/2; i <len-1; i++)
     43     {
     44         if(i < j)swap(y[i],y[j]);
     45         //交换互为小标反转的元素,i<j保证交换一次
     46         //i做正常的+1,j左反转类型的+1,始终保持i和j是反转的
     47         k = len/2;
     48         while(j >= k)
     49         {
     50             j -= k;
     51             k /= 2;
     52         }
     53         if(j < k)j += k;
     54     }
     55 }
     56 /*
     57 *做FFT
     58 * len必须为2^k形式,
     59 * on==1时是DFT,on==-1时是IDFT
     60 */
     61 //fft(x,len,1):对向量x做DFT(时域->频域),向量长度为1--len
     62 //fft(x,len,-1):做IDFT(频域->时域)
     63 void fft(Complex y[],int len,int  on)
     64 {
     65     change(y,len);
     66     for(int h = 2; h <= len; h <<= 1)
     67     {
     68         Complex wn(cos(-on*2*PI/h),sin(-on*2*PI/h));
     69         for(int j = 0; j < len; j+=h)
     70         {
     71             Complex  w(1,0);
     72             for(int k = j; k < j+h/2; k++)
     73             {
     74                 Complex u = y[k];
     75                 Complex t = w*y[k+h/2];
     76                 y[k] = u+t;
     77                 y[k+h/2] = u-t;
     78                 w = w*wn;
     79             }
     80         }
     81     }
     82     if(on == -1)
     83         for(int i = 0; i < len; i++)
     84             y[i].x /= len;
     85 }
     86 
     87 Complex x[MAXL];
     88 LL nx[MAXL],tri[MAXN],sx[MAXL],NUM[MAXL];
     89 int TIMES,N,tm;
     90 
     91 int main()
     92 {
     93     scanf("%d",&TIMES);
     94     for (int Times=1;Times<=TIMES;Times++)
     95     {
     96         scanf("%d",&N);
     97 
     98         memset(nx,0,sizeof(nx));
     99         memset(sx,0,sizeof(sx));
    100         memset(x,0,sizeof(x));
    101         memset(NUM,0,sizeof(NUM));
    102 
    103         for (int i=0;i<N;i++)
    104         {
    105             scanf("%d",&tri[i]);
    106             NUM[tri[i]]++;
    107         }
    108 
    109         sort(tri,tri+N);
    110         int mx=tri[N-1];
    111         int l1=mx+1;
    112         int len=1;
    113         while (len<2*l1) len<<=1;
    114         for (int i=0;i<l1;i++)
    115             x[i]=Complex(NUM[i],0);
    116         for (int i=l1;i<len;i++)
    117             x[i]=Complex(0,0);
    118 
    119         fft(x,len,1);
    120 
    121         for (int i=0;i<len;i++)
    122             x[i]=x[i]*x[i];
    123 
    124         fft(x,len,-1);
    125         for (int i=0;i<len;i++)
    126             nx[i]=(LL)(x[i].x+0.5);
    127 
    128         len=2*mx;
    129         for (int i=0;i<N;i++)
    130             nx[tri[i]*2]--;
    131         for (int i=1;i<=len;i++)
    132             nx[i]=nx[i]/2;
    133 /*
    134         for (int i=0;i<=len;i++)
    135             cout<<nx[i]<<" ";
    136         cout<<endl;
    137 */
    138         sx[0]=0;
    139         for (int i=1;i<=len;i++)
    140             sx[i]=sx[i-1]+nx[i];
    141 /*
    142         for (int i=0;i<=len;i++)
    143             cout<<sx[i]<<" ";
    144         cout<<endl;
    145 */
    146         LL tot=0;
    147         for (int i=0;i<N;i++)
    148         {
    149             tot+=sx[len]-sx[tri[i]];
    150             tot-=(LL)(N-i-1)*i;
    151             tot-=(N-1);
    152             tot-=(LL)(N-1-i)*(N-i-2)/2;
    153         }
    154         //cout<<tot<<endl;
    155         LL kk=(LL)(N*(N-1)*(N-2)/6);
    156         //cout<<tot<<" "<<kk<<endl;
    157         printf("%.7lf
    ",(double)tot/kk);
    158     }
    159 
    160     return 0;
    161 }
    View Code

    ref:http://www.cnblogs.com/kuangbin/archive/2013/07/24/3210565.html

  • 相关阅读:
    一步一步使用Ext JS MVC与Asp.Net MVC 3开发简单的CMS后台管理系统之用户管理(1)
    一步一步使用Ext JS MVC与Asp.Net MVC 3开发简单的CMS后台管理系统之创建Viewport(2)
    一步一步使用Ext JS MVC与Asp.Net MVC 3开发简单的CMS后台管理系统之用户管理(2)
    一步一步使用Ext JS MVC与Asp.Net MVC 3开发简单的CMS后台管理系统之完成登录功能
    一步一步使用Ext JS MVC与Asp.Net MVC 3开发简单的CMS后台管理系统之登录窗口调试
    一步一步使用Ext JS MVC与Asp.Net MVC 3开发简单的CMS后台管理系统之创建Viewport(1)
    一步一步使用Ext JS MVC与Asp.Net MVC 3开发简单的CMS后台管理系统之创建输出验证码图片的控制器
    一步一步使用Ext JS MVC与Asp.Net MVC 3开发简单的CMS后台管理系统之调整首页显示
    一步一步使用Ext JS MVC与Asp.Net MVC 3开发简单的CMS后台管理系统之登录窗口
    一步一步使用Ext JS MVC与Asp.Net MVC 3开发简单的CMS后台管理系统之用户管理(3)
  • 原文地址:https://www.cnblogs.com/pdev/p/4463823.html
Copyright © 2011-2022 走看看