比较裸的FFT(快速傅里叶变换),也是为了这道题而去学的,厚的白书上有简单提到,不过还是推荐看算法导论,讲的很详细。

代码的话是照着别人敲的,推荐:http://www.cnblogs.com/kuangbin/archive/2013/07/24/3210565.html写的很详细。

  1. #include<cstdio>
  2. #include<cstring>
  3. #include<algorithm>
  4. #include<cmath>
  5. using namespace std;
  6. #define LL __int64
  7.  
  8. const double PI=acos(-1.0);
  9.  
  10. struct complex{ //实数:r实部,i虚部
  11. double r,i;
  12. complex(double rr=,double ii=)
  13. {
  14. r=rr;
  15. i=ii;
  16. }
  17. complex operator +(const complex &b)
  18. {
  19. return complex(r+b.r,i+b.i);
  20. }
  21. complex operator -(const complex &b)
  22. {
  23. return complex(r-b.r,i-b.i);
  24. }
  25. complex operator *(const complex &b)
  26. {
  27. return complex(r*b.r-i*b.i,r*b.i+i*b.r);
  28. }
  29. };
  30.  
  31. void change(complex y[],int len) //位逆序置换
  32. {
  33. int i,j,k;
  34. for(i=,j=len/;i<len-;i++)
  35. {
  36. if(i<j)
  37. swap(y[i],y[j]);
  38. k=len/;
  39. while(j>=k)
  40. {
  41. j-=k;
  42. k/=;
  43. }
  44. if(j<k)
  45. j+=k;
  46. }
  47. }
  48.  
  49. void fft(complex y[],int len,int on)
  50. {
  51. change(y,len);
  52. for(int h=;h<=len;h<<=)
  53. {
  54. complex wn(cos(-on**PI/h),sin(-on**PI/h));
  55. for(int j=;j<len;j+=h)
  56. {
  57. complex w(,);
  58. for(int k=j;k<j+h/;k++)
  59. {
  60. complex u=y[k];
  61. complex t=w*y[k+h/];
  62. y[k]=u+t;
  63. y[k+h/]=u-t;
  64. w=w*wn;
  65. }
  66. }
  67. }
  68. if(on==-)
  69. for(int i=;i<len;i++)
  70. y[i].r/=len;
  71. }
  72.  
  73. const int MAXN=;
  74. complex x1[MAXN];
  75. int a[MAXN/];
  76. LL num[MAXN];
  77. LL sum[MAXN];
  78.  
  79. int main()
  80. {
  81. int T,n;
  82. scanf("%d",&T);
  83. while(T--)
  84. {
  85. scanf("%d",&n);
  86. memset(num,,sizeof(num));
  87. for(int i=;i<n;i++)
  88. {
  89. scanf("%d",&a[i]);
  90. num[a[i]]++;
  91. }
  92. //FFT
  93. sort(a,a+n);
  94. int len1=a[n-]+;
  95. int len=;
  96. while(len<*len1)
  97. len<<=;
  98. for(int i=;i<len1;i++)
  99. x1[i]=complex(num[i],);
  100. for(int i=len1;i<len;i++) //补0
  101. x1[i]=complex(,);
  102. fft(x1,len,); //求值
  103. for(int i=;i<len;i++) //乘法
  104. x1[i]=x1[i]*x1[i];
  105. fft(x1,len,-); //插值
  106. //
  107. for(int i=;i<len;i++)
  108. num[i]=(LL)(x1[i].r+0.5);
  109. len=*a[n-];
  110. for(int i=;i<n;i++)
  111. num[a[i]+a[i]]--;
  112. for(int i=;i<=len;i++)
  113. num[i]/=;
  114. sum[]=;
  115. for(int i=;i<=len;i++)
  116. sum[i]=sum[i-]+num[i];
  117. LL cnt=;
  118. for(int i=;i<n;i++)
  119. {
  120. cnt+=sum[len]-sum[a[i]];
  121. cnt-=(LL)(n--i)*(n-i-)/;
  122. cnt-=(n-);
  123. cnt-=(LL)(n--i)*(n-i-)/;
  124. }
  125. LL tot=(LL)n*(n-)*(n-)/;
  126. printf("%.7f\n",(double)cnt/tot);
  127. }
  128. return ;
  129. }

hdu 4609 3-idiots(快速傅里叶FFT)的更多相关文章

  1. 解题:HDU 4609 Three Idiots

    题面 要求组合的方法显然我们需要对桶卷积,即设$F(x)=\sum\limits_{i=1}^{maxx}x^{cnt[i]}$,然后我们初步的先把$F^2(x)$卷出来,表示选两条边.然后我们发现如 ...

  2. hdu 4609 3-idiots [fft 生成函数 计数]

    hdu 4609 3-idiots 题意: 给出\(A_i\),问随机选择一个三元子集,选择的数字构成三角形的三边长的概率. 一开始一直想直接做.... 先生成函数求选两个的方案(注意要减去两次选择同 ...

  3. 快速傅里叶变换应用之二 hdu 4609 3-idiots

    快速傅里叶变化有不同的应用场景,hdu4609就比较有意思.题目要求是给n个线段,随机从中选取三个,组成三角形的概率. 初始实在没发现这个怎么和FFT联系起来,后来看了下别人的题解才突然想起来:组合计 ...

  4. hdu 4609 3-idiots <FFT>

    链接: http://acm.hdu.edu.cn/showproblem.php?pid=4609 题意: 给定 N 个正整数, 表示 N 条线段的长度, 问任取 3 条, 可以构成三角形的概率为多 ...

  5. HDU 4609 3-idiots(FFT)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4609 题意:给出n个正整数(数组A).每次随机选出三个数.问这三个数能组成三角形的概率为多大? 思路: ...

  6. HDU 4609 FFT模板

    http://acm.hdu.edu.cn/showproblem.php?pid=4609 题意:给你n个数,问任意取三边能够,构成三角形的概率为多少. 思路:使用FFT对所有长度的个数进行卷积(\ ...

  7. hdu 4609 3-idiots——FFT

    题目:http://acm.hdu.edu.cn/showproblem.php?pid=4609 答案就是随便选三条边的方案 - 不合法的方案. 不合法的方案就是算出 x+y = k 的方案数 g[ ...

  8. hdu 4609 3-idiots —— FFT

    题目:http://acm.hdu.edu.cn/showproblem.php?pid=4609 算不合法的比较方便: 枚举最大的边,每种情况算了2次,而全排列算了6次,所以还要乘3: 注意枚举最大 ...

  9. FFT(快速傅里叶变换):HDU 4609 3-idiots

    3-idiots Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total S ...

随机推荐

  1. c# 取 list前100条数据

    [问] List<KeyWord> sortedList = (from a in keyWordList orderby a.Total descending select a).ToL ...

  2. request 路径随笔

    1. 路劲可分为 绝对路径 和 相对路径 2. 绝对路径 (开头带"/") 前端: http://localhost:8080/myWebApp/user/login.jsp /m ...

  3. Unity3D研究院之与Android相互传递消息

    原地址:http://www.xuanyusong.com/archives/676 上一篇文章我们学习了Unity向Android发送消息,如果Android又能给Unity回馈消息那么这就玩美了. ...

  4. SPOJ LGLOVE 7488 LCM GCD Love (区间更新,预处理出LCM(1,2,...,n))

    题目连接:http://www.spoj.com/problems/LGLOVE/ 题意:给出n个初始序列a[1],a[2],...,a[n],b[i]表示LCM(1,2,3,...,a[i]),即1 ...

  5. [C++]默认构造函数

    默认构造函数(default constructor)就是在没有显示提供初始化式时调用的构造函数.它由不带参数的构造函数,或者为所有的形参提供默认实参的构造函数定义.若个定义某个类的变量时没有提供初始 ...

  6. hibernate的简单学习(第一天)

    sql脚本: -- Create table drop table T_PERSON; create table T_PERSON ( id ) PRIMARY KEY, name ), passwo ...

  7. 如何在linux系统下对文件夹名有空格的文件夹进行操作

    http://www.2cto.com/os/201409/335119.html 在Windows操作系统中可以轻易地创建\移动\删除文件夹名带有空格的文件夹, 而在linux则需要进行一些特殊的处 ...

  8. 自动装配【Spring autowire】

    public class AutoWiringDao { private String daoName; public void setDaoName(String daoName) { this.d ...

  9. JAVA:23种设计模式详解(转)

    设计模式(Design Patterns) ——可复用面向对象软件的基础 设计模式(Design pattern)是一套被反复使用.多数人知晓的.经过分类编目的.代码设计经验的总结.使用设计模式是为了 ...

  10. C# 对象与JSON串互相转换(转)

    DoNet2.0 需要借助于Newtonsoft.Json.dll 代码 using System;using System.IO;using System.Text;using Newtonsoft ...