Problem Description
King OMeGa catched three men who had been streaking in the street. Looking as idiots though, the three men insisted that it was a kind of performance art, and begged the king to free them. Out of hatred to the real idiots, the king wanted to check if they were lying. The three men were sent to the king's forest, and each of them was asked to pick a branch one after another. If the three branches they bring back can form a triangle, their math ability would save them. Otherwise, they would be sent into jail.
However, the three men were exactly idiots, and what they would do is only to pick the branches randomly. Certainly, they couldn't pick the same branch - but the one with the same length as another is available. Given the lengths of all branches in the forest,
determine the probability that they would be saved.
 
Input
An integer T(T≤100) will exist in the first line of input, indicating the number of test cases.
Each test case begins with the number of branches N(3≤N≤105).
The following line contains N integers a_i (1≤a_i≤105), which denotes the length of each branch, respectively.
 
Output
Output the probability that their branches can form a triangle, in accuracy of 7 decimal places.
 
Sample Input
2
4
1 3 3 4
4
2 3 3 4
 
Sample Output
0.5000000
1.0000000

题意:给你n个边,求从其中选出3个组成三角形的概率

思路:参考-kuangbin大神

如果我们用num[i]表示长度为i的木棍有多少个,对于1 3 3 4就是

num[] = {0 1 0 2 1}从卷积的公式来看

乘法第k位置上的值 便是a[i]*b[j](i + j == k),如果位置表示的是长度,num[]表示的个数,那么卷积过后我们得到的便是两边和的个数

{0 1 0 2 1}*{0 1 0 2 1} 卷积的结果应该是{0 0  1  0  4  2  4  4  1 }。

在求出了两条边的和后,枚举第三边

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
typedef long long ll;
typedef long double ld;
const ld eps=1e-10;
const int inf = 0x3f3f3f;
const int MOD = 1e9+7; const double PI = acos(-1.0); struct Complex
{
double x,y;
Complex(double _x = 0.0,double _y = 0.0)
{
x = _x;
y = _y;
}
Complex operator-(const Complex &b)const
{
return Complex(x-b.x,y-b.y);
}
Complex operator+(const Complex &b)const
{
return Complex(x+b.x,y+b.y);
}
Complex operator*(const Complex &b)const
{
return Complex(x*b.x-y*b.y,x*b.y+y*b.x);
}
}; void change(Complex y[],int len)
{
int i,j,k;
for(i = 1,j = len/2; i < len-1; i++)
{
if(i < j) swap(y[i],y[j]);
k = len/2;
while(j >= k)
{
j-=k;
k/=2;
}
if(j < k) j+=k;
}
} void fft(Complex y[],int len,int on)
{
change(y,len);
for(int h = 2; h <= len; h <<= 1)
{
Complex wn(cos(-on*2*PI/h),sin(-on*2*PI/h));
for(int j = 0; j < len; j+=h)
{
Complex w(1,0);
for(int k = j; k < j+h/2; k++)
{
Complex u = y[k];
Complex t = w*y[k+h/2];
y[k] = u+ t;
y[k+h/2] = u-t;
w = w*wn;
}
}
}
if(on == -1)
{
for(int i = 0; i < len; i++)
y[i].x /= len;
}
} const int maxn = 401000;
Complex x1[maxn],x2[maxn];
ll sum[maxn];
ll num[maxn];
int a[maxn]; int main()
{
int T;
int n;
scanf("%d",&T);
while(T--)
{
scanf("%d",&n);
int len = 1;
int len1;
memset(num,0,sizeof(num));
for(int i = 0; i < n; i++)
{
scanf("%d",&a[i]);
num[a[i]]++;
}
sort(a,a+n);
len1 = a[n-1] + 1;
while(len < len1*2) len <<= 1; for(int i = 0; i < len1; i++)
x1[i] = Complex(num[i],0);
for(int i = len1; i < len; i++)
x1[i] = Complex(0,0); fft(x1,len,1);
//fft(x2,len,1);
for(int i = 0; i < len; i++)
{
x1[i] =x1[i]*x1[i];
//cout << x1[i].x << " "<< x1[i].y <<endl;
}
fft(x1,len,-1);
for(int i = 0; i < len; i++)
{
sum[i] = (ll)(x1[i].x+0.5);
//cout << sum[i] << endl;
}
len = a[n-1] * 2;
for(int i = 0; i < n; i++) sum[a[i]+a[i]] --;
for(int i = 1; i <= len; i++) sum[i] /= 2;
for(int i = 1; i <= len; i++)
{
sum[i] += sum[i-1];
}
ll tot = (ll)n*(n-1)*(n-2)/6;
ll ans = 0; for(int i = 0; i < n; i++)
{
ans += sum[len]-sum[a[i]]; //两边之和大于第三边 ans -= (ll)(n-1-i) * i; //一个比自己大,一个比自己小
ans -= (n-1); //取了自己
ans -= (ll)(n-1-i)*(n-2-i)/2; //都比自己大
}
//printf("%.7lf\n",(double)ans/tot);
printf("%.7f\n",(double)ans/tot);
}
return 0;
}

  

hdu 4609 (FFT求解三角形)的更多相关文章

  1. HDU 4609 FFT模板

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

  2. hdu 4609 FFT

    题意:给出一堆数,问从这些数中取3个能组成三角形的概率? sol:其实就是问从这些数里取3个组成三角形有多少种取法 脑洞大开的解法:用FFT 设一开始的数是1 3 3 4 作一个向量x,其中x[i]= ...

  3. HDU 4609 FFT+组合数学

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

  4. HDU 4609 FFT+各种分类讨论

    思路: http://www.cnblogs.com/kuangbin/archive/2013/07/24/3210565.html 其实我是懒得写了.... 一定要define int long ...

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

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

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

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

  7. hdu 4609 3-idiots

    http://acm.hdu.edu.cn/showproblem.php?pid=4609 FFT  不会 找了个模板 代码: #include <iostream> #include ...

  8. hdu 5830 FFT + cdq分治

    Shell Necklace Time Limit: 16000/8000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)T ...

  9. hdu 5885 FFT

    XM Reserves Time Limit: 10000/10000 MS (Java/Others)    Memory Limit: 102400/102400 K (Java/Others)T ...

随机推荐

  1. 利用python处理文档中各字段出现的次数并排序

    import string path = 'waldnn' with open(path,'r') as text: words = [raw_word.strip(string.punctuatio ...

  2. c 语言typedef 和 define的使用和区别

    #define是C的指令,用于为各种数据类型定义别名,与typedef 类似,但是有一下几点不同 1,typedef仅限于为类型定义符号名称,而#define不仅可以为类型定义符号名称,也能为数值定义 ...

  3. VMware网络配置

    NAT模式 首先保证虚拟机网卡和主机对接,虚拟机网络连接要和主机在同一网段 1. 控制面板\网络和 Internet\网络连接中配置VMnet8 2. 编辑虚拟机网络配置 此处子网ip需要和Vnet8 ...

  4. 获取apk项目的MD5值和SHA1值

    一些可说可不说的话: * 以前有一个更简单的方法,在as的右边工具栏的 gradle 面板中可以很方便的获取到: * 上次用也是在2年前,时间长了给忘记了,不过我记得我当时写了笔记,这会笔记不在身边, ...

  5. SpringBoot的RestController vs @ResponseBody + @Controller

    @Controller和@RestController的区别?官方文档:@RestController is a stereotype annotation that combines @Respon ...

  6. HTTP协议扫盲(六)InputStream的复用

    一.问题提出 在进行网关引擎开发时,获取到一个http请求的inputstream后,可能要多次利用它进行read操作.由于流读过一次就不能再读了,所以需要实现InputStream的复制. 而Inp ...

  7. apacheds的客户端

    Apache DS管理的JAVA实现 LdapConnection connection = new LdapNetworkConnection("localhost", 1038 ...

  8. AOP及专有名词通俗解答

    AOP面向切面编程,是一种编程思想,并不是Spring专有,Spring是封装代理模式完成,之前的博客中也写到了关于AOP的文章,Filter和代理,请见<以此之长,补彼之短----AOP(Fi ...

  9. java循环遍历类属性 get 和set值方法

    //遍历sqspb类 成员为String类型 属性为空的全部替换为"/"Field[] fields = sqspb.getClass().getDeclaredFields(); ...

  10. python基础——类名称空间与对象(实例)名称空间

    python基础--类名称空间与对象(实例)名称空间 1 类名称空间 创建一个类就会创建一个类的名称空间,用来存储类中定义的所有名字,这些名字称为类的属性 而类的良好总属性:数据属性和函数属性 其中类 ...