hdu 4609 3-idiots(快速傅里叶FFT)
比较裸的FFT(快速傅里叶变换),也是为了这道题而去学的,厚的白书上有简单提到,不过还是推荐看算法导论,讲的很详细。
代码的话是照着别人敲的,推荐:http://www.cnblogs.com/kuangbin/archive/2013/07/24/3210565.html写的很详细。
- #include<cstdio>
- #include<cstring>
- #include<algorithm>
- #include<cmath>
- using namespace std;
- #define LL __int64
- const double PI=acos(-1.0);
- struct complex{ //实数:r实部,i虚部
- double r,i;
- complex(double rr=,double ii=)
- {
- r=rr;
- i=ii;
- }
- complex operator +(const complex &b)
- {
- return complex(r+b.r,i+b.i);
- }
- complex operator -(const complex &b)
- {
- return complex(r-b.r,i-b.i);
- }
- complex operator *(const complex &b)
- {
- return complex(r*b.r-i*b.i,r*b.i+i*b.r);
- }
- };
- void change(complex y[],int len) //位逆序置换
- {
- int i,j,k;
- for(i=,j=len/;i<len-;i++)
- {
- if(i<j)
- swap(y[i],y[j]);
- k=len/;
- while(j>=k)
- {
- j-=k;
- k/=;
- }
- if(j<k)
- j+=k;
- }
- }
- void fft(complex y[],int len,int on)
- {
- change(y,len);
- for(int h=;h<=len;h<<=)
- {
- complex wn(cos(-on**PI/h),sin(-on**PI/h));
- for(int j=;j<len;j+=h)
- {
- complex w(,);
- for(int k=j;k<j+h/;k++)
- {
- complex u=y[k];
- complex t=w*y[k+h/];
- y[k]=u+t;
- y[k+h/]=u-t;
- w=w*wn;
- }
- }
- }
- if(on==-)
- for(int i=;i<len;i++)
- y[i].r/=len;
- }
- const int MAXN=;
- complex x1[MAXN];
- int a[MAXN/];
- LL num[MAXN];
- LL sum[MAXN];
- int main()
- {
- int T,n;
- scanf("%d",&T);
- while(T--)
- {
- scanf("%d",&n);
- memset(num,,sizeof(num));
- for(int i=;i<n;i++)
- {
- scanf("%d",&a[i]);
- num[a[i]]++;
- }
- //FFT
- sort(a,a+n);
- int len1=a[n-]+;
- int len=;
- while(len<*len1)
- len<<=;
- for(int i=;i<len1;i++)
- x1[i]=complex(num[i],);
- for(int i=len1;i<len;i++) //补0
- x1[i]=complex(,);
- fft(x1,len,); //求值
- for(int i=;i<len;i++) //乘法
- x1[i]=x1[i]*x1[i];
- fft(x1,len,-); //插值
- //
- for(int i=;i<len;i++)
- num[i]=(LL)(x1[i].r+0.5);
- len=*a[n-];
- for(int i=;i<n;i++)
- num[a[i]+a[i]]--;
- for(int i=;i<=len;i++)
- num[i]/=;
- sum[]=;
- for(int i=;i<=len;i++)
- sum[i]=sum[i-]+num[i];
- LL cnt=;
- for(int i=;i<n;i++)
- {
- cnt+=sum[len]-sum[a[i]];
- cnt-=(LL)(n--i)*(n-i-)/;
- cnt-=(n-);
- cnt-=(LL)(n--i)*(n-i-)/;
- }
- LL tot=(LL)n*(n-)*(n-)/;
- printf("%.7f\n",(double)cnt/tot);
- }
- return ;
- }
hdu 4609 3-idiots(快速傅里叶FFT)的更多相关文章
- 解题:HDU 4609 Three Idiots
题面 要求组合的方法显然我们需要对桶卷积,即设$F(x)=\sum\limits_{i=1}^{maxx}x^{cnt[i]}$,然后我们初步的先把$F^2(x)$卷出来,表示选两条边.然后我们发现如 ...
- hdu 4609 3-idiots [fft 生成函数 计数]
hdu 4609 3-idiots 题意: 给出\(A_i\),问随机选择一个三元子集,选择的数字构成三角形的三边长的概率. 一开始一直想直接做.... 先生成函数求选两个的方案(注意要减去两次选择同 ...
- 快速傅里叶变换应用之二 hdu 4609 3-idiots
快速傅里叶变化有不同的应用场景,hdu4609就比较有意思.题目要求是给n个线段,随机从中选取三个,组成三角形的概率. 初始实在没发现这个怎么和FFT联系起来,后来看了下别人的题解才突然想起来:组合计 ...
- hdu 4609 3-idiots <FFT>
链接: http://acm.hdu.edu.cn/showproblem.php?pid=4609 题意: 给定 N 个正整数, 表示 N 条线段的长度, 问任取 3 条, 可以构成三角形的概率为多 ...
- HDU 4609 3-idiots(FFT)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4609 题意:给出n个正整数(数组A).每次随机选出三个数.问这三个数能组成三角形的概率为多大? 思路: ...
- HDU 4609 FFT模板
http://acm.hdu.edu.cn/showproblem.php?pid=4609 题意:给你n个数,问任意取三边能够,构成三角形的概率为多少. 思路:使用FFT对所有长度的个数进行卷积(\ ...
- hdu 4609 3-idiots——FFT
题目:http://acm.hdu.edu.cn/showproblem.php?pid=4609 答案就是随便选三条边的方案 - 不合法的方案. 不合法的方案就是算出 x+y = k 的方案数 g[ ...
- hdu 4609 3-idiots —— FFT
题目:http://acm.hdu.edu.cn/showproblem.php?pid=4609 算不合法的比较方便: 枚举最大的边,每种情况算了2次,而全排列算了6次,所以还要乘3: 注意枚举最大 ...
- FFT(快速傅里叶变换):HDU 4609 3-idiots
3-idiots Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total S ...
随机推荐
- c# 取 list前100条数据
[问] List<KeyWord> sortedList = (from a in keyWordList orderby a.Total descending select a).ToL ...
- request 路径随笔
1. 路劲可分为 绝对路径 和 相对路径 2. 绝对路径 (开头带"/") 前端: http://localhost:8080/myWebApp/user/login.jsp /m ...
- Unity3D研究院之与Android相互传递消息
原地址:http://www.xuanyusong.com/archives/676 上一篇文章我们学习了Unity向Android发送消息,如果Android又能给Unity回馈消息那么这就玩美了. ...
- 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 ...
- [C++]默认构造函数
默认构造函数(default constructor)就是在没有显示提供初始化式时调用的构造函数.它由不带参数的构造函数,或者为所有的形参提供默认实参的构造函数定义.若个定义某个类的变量时没有提供初始 ...
- hibernate的简单学习(第一天)
sql脚本: -- Create table drop table T_PERSON; create table T_PERSON ( id ) PRIMARY KEY, name ), passwo ...
- 如何在linux系统下对文件夹名有空格的文件夹进行操作
http://www.2cto.com/os/201409/335119.html 在Windows操作系统中可以轻易地创建\移动\删除文件夹名带有空格的文件夹, 而在linux则需要进行一些特殊的处 ...
- 自动装配【Spring autowire】
public class AutoWiringDao { private String daoName; public void setDaoName(String daoName) { this.d ...
- JAVA:23种设计模式详解(转)
设计模式(Design Patterns) ——可复用面向对象软件的基础 设计模式(Design pattern)是一套被反复使用.多数人知晓的.经过分类编目的.代码设计经验的总结.使用设计模式是为了 ...
- C# 对象与JSON串互相转换(转)
DoNet2.0 需要借助于Newtonsoft.Json.dll 代码 using System;using System.IO;using System.Text;using Newtonsoft ...