题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4609

题意:n个数,问取三个数可以构成三角形的组合数。

FFT预处理出两个数的组合情况,然后枚举第三个数,计数去重。

 #include <bits/stdc++.h>
using namespace std; const double PI = acos(-1.0);
//复数结构体
typedef struct Complex {
double r,i;
Complex(double _r = 0.0,double _i = 0.0) {
r = _r; i = _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);
}
Complex operator *(const Complex &b) {
return Complex(r*b.r-i*b.i,r*b.i+i*b.r);
}
}Complex;
/*
* 进行FFT和IFFT前的反转变换。
* 位置i和 (i二进制反转后位置)互换
* len必须是2的幂
*/
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]);
//交换互为小标反转的元素,i<j保证交换一次
//i做正常的+1,j左反转类型的+1,始终保持i和j是反转的
k = len/;
while( j >= k) {
j -= k;
k /= ;
}
if(j < k) j += k;
}
}
/*
* 做FFT
* len必须为2^k形式,
* on==1时是DFT,on==-1时是IDFT
*/
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;
}
}
} typedef long long LL;
const int maxn = ;
Complex x1[maxn];
int a[maxn/];
LL num[maxn], s[maxn];
int n, len, q; int main() {
// freopen("in", "r", stdin);
int T;
scanf("%d", &T);
while(T--) {
scanf("%d",&n);
memset(a, , sizeof(a));
memset(s, , sizeof(s));
memset(num, , sizeof(num));
int maxx = ;
for(int i = ; i < n; i++) {
scanf("%I64d", &a[i]);
num[a[i]]++;
maxx = max(maxx, a[i]);
}
int len1 = maxx + ;
len = ;
while(len < len1 * ) len <<= ;
for(int i = ; i < len; i++) x1[i] = Complex(, );
for(int i = ; i < len1; i++) x1[i] = Complex(num[i], );
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 = * maxx;
for(int i = ; i < n; i++) num[a[i]*]--;
for(int i = ; i <= len; i++) num[i] /= ;
for(int i = ; i <= len; i++) s[i] = s[i-] + num[i];
LL ret = ;
for(int i = ; i < n; i++) {
ret += s[len] - s[a[i]];
ret -= (LL)(n - i - ) * i;
ret -= (n - );
ret -= (LL)(n - i - ) * (n - i - ) / ;
}
LL sum = (LL)n * (n - ) * (n - ) / ;
// cout << (double)ret/(double)((n*(n-1)*(n-2))/6) << endl;
printf("%.7lf\n", (double)ret/sum);
}
return ;
}

[HDOJ4609]3-idiots(FFT,计数)的更多相关文章

  1. bzoj 3513: [MUTC2013]idiots FFT

    bzoj 3513: [MUTC2013]idiots FFT 链接 bzoj 思路 参考了学姐TRTTG的题解 统计合法方案,最后除以总方案. 合法方案要不好统计,统计不合法方案. \(a+b< ...

  2. bzoj 3513 [MUTC2013]idiots FFT 生成函数

    [MUTC2013]idiots Time Limit: 20 Sec  Memory Limit: 128 MBSubmit: 806  Solved: 265[Submit][Status][Di ...

  3. BZOJ3513[MUTC2013]idiots——FFT+生成函数

    题目描述 给定n个长度分别为a_i的木棒,问随机选择3个木棒能够拼成三角形的概率. 输入 第一行T(T<=100),表示数据组数. 接下来若干行描述T组数据,每组数据第一行是n,接下来一行有n个 ...

  4. [MUTC2013][bzoj3513] idiots [FFT]

    题面 传送门 思路 首先有一个容斥原理的结论:可以组成三角形的三元组数量=所有三元组-不能组成三角形的三元组 也就是说我们只要求出所有不能组成三角形的三元组即可 我们考虑三元组(a,b,c),a< ...

  5. [UVA 12633] Super Rooks on Chessboard FFT+计数

    如果只有行和列的覆盖,那么可以直接做,但现在有左上到右下的覆盖. 考虑对行和列的覆盖情况做一个卷积,然后就有了x+y的非覆盖格子数. 然后用骑士的左上到右下的覆盖特判掉那些x+y的格子就可以了. 注意 ...

  6. [HDU4609] 3-idiots FFT+计数

    用FFT再去重计算出两条边加起来为某个值得方案数,然后用总方案数减去不合法方案数即可. #include<iostream> #include<cstdio> #include ...

  7. 【bzoj3513】[MUTC2013]idiots FFT

    题目描述 给定n个长度分别为a_i的木棒,问随机选择3个木棒能够拼成三角形的概率. 输入 第一行T(T<=100),表示数据组数. 接下来若干行描述T组数据,每组数据第一行是n,接下来一行有n个 ...

  8. ACM第一阶段学习内容

    一.知识目录 字符串处理 ................................................................. 3 1.KMP 算法 .......... ...

  9. [loj6051]PATH

    (不妨将下标改为从1开始) 参考loj2265中关于杨表的相关知识 构造一个$n$行且第$i$行有$a_{i}$个格子的杨表,依次记录其每一次增加的时间(范围为$[1,\sum_{i=1}^{n}a_ ...

随机推荐

  1. 二招解决php乱码问题

    PHP的乱码问题已经说了N+1遍了,但还是经常看到新手不知道该如何解决php乱码问题,在此本人再重新给总结一下,希望对新手有点帮助 php网页出现乱码一般是在建立数据库时用的编码和php网页的编码不同 ...

  2. opencv之深拷贝及浅拷贝,IplImage装换为Mat

    一.(1)  浅拷贝: Mat B; B = image  // 第一种方式 Mat C(image); // 第二种方式 这两种方式称为浅copy,是由于它们有不同的矩阵头,但是它们共享内存空间,即 ...

  3. java技术用ssh从linux服务器下载数据

    通常需要从linux服务器获取数据文件,而通常能有的访问方式只有ssh,所以就可以用ssh进行数据下载. java连接远程主机的方式有多种,这里和大家分享的是通过ssh方式连接远程主机,使用的是jsc ...

  4. flex 添加右键链接

    private var myMenu:ContextMenu; private function setViewerVersion():void { var menuItem:ContextMenuI ...

  5. 【转载】Perl异常处理方法总结

    程序脚本在运行过程中,总会碰到这样那样的问题,我们会预知一些问题并为其准备好处理代码,而有一些不能预知.好的程序要能尽可能多的处理可能出现的异常问题,本文就总结了一些方法来解决这些异常,当然perl在 ...

  6. [转]Jexus的常用操作和基本配置

    转自http://www.cnblogs.com/xiaodiejinghong/archive/2013/04/05/3000404.html 3.Jexus的操作 经过两个章节关于Jexus的介绍 ...

  7. C#:控制WinForm界面的显示

    控制WinForm界面在屏幕的四个角落显示,具体代码中有说明: using System; using System.Collections.Generic; using System.Drawing ...

  8. javascript事件处理解析

    一.什么是事件!(w3c解释) 事件是可以被 JavaScript 侦测到的行为. JavaScript 使我们有能力创建动态页面.事件是可以被 JavaScript 侦测到的行为. 网页中的每个元素 ...

  9. Shopping(SPFA+DFS HDU3768)

    Shopping Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Sub ...

  10. Children of the Candy Corn 分类: POJ 2015-07-14 08:19 7人阅读 评论(0) 收藏

    Children of the Candy Corn Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 10933   Acce ...