题目链接: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. 161206、 Ionic、Angularjs、Cordova搭建Android开发环境

    1.jdk 环境变量配置 path:C:\Program Files\Java\jdk1.7.0_79\bin 2.Node.js 因为安装cordova时要用到node.js的npm 下载地址: h ...

  2. Linux 进程状态【转】

    转自:http://www.cnblogs.com/itech/p/3208261.html 来自: http://blog.csdn.net/tianlesoftware/article/detai ...

  3. 转Class.forName()用法详解

    主要功能 Class.forName(xxx.xx.xx)返回的是一个类 Class.forName(xxx.xx.xx)的作用是要求JVM查找并加载指定的类, 也就是说JVM会执行该类的静态代码段 ...

  4. 在ECSHOP后台的订单列表中显示配送方式

    熟悉ECSHOP后台的人都知道,只有点击某个具体的订单,进入订单详细页面才能看到该订单的配送方式,最模板修改的目的,是想让管理者在订单列表页面 就能看到该订单的配送方式. 下面是修改方法:首先来修改 ...

  5. Oracle存储过程单步调试方法

    oracle存储过程单步调试的方法 1.在要调试的过程上单击test,如下图所示: 2.出现如下界面时单击最左上方的按钮:,如下图所示: 3.单击后呈现如下画面: 其中: 表示要停止test; 表示要 ...

  6. vi复制文字

    可以对文字使用标记,在光标处使用 ma 将该行标记为a,可用`a (反引号)定位到该标记a位置,用'a (单引号)定位到该行行首. d$删除光标位置到行尾,y$取光标位置到行尾.d和y也可配合标记使用 ...

  7. shell基础二十篇 一些笔记

    shell基础二十篇 转自 http://bbs.chinaunix.net/thread-452942-1-1.html 研讨:Bash 内建命令 read (read命令更具体的说明见博客收藏的一 ...

  8. URL List

    wifi driver http://wenku.baidu.com/view/5fb275e9b8f67c1cfad6b85e.html http://wenku.baidu.com/view/a5 ...

  9. 【转】Eclipse插件大全介绍及下载地址

    转载地址:http://developer.51cto.com/art/200906/127169.htm 尚未一一验证. eclipse插件大全介绍,以及下载地址 Eclipse及其插件下载网址大全 ...

  10. c# 中的日期格式

    输出日期格式是:美国时间 :Tue Oct 22 xxxx 00:00:00 GMT+0800  第一种: string strDate = "Mon Aug 15 2011 00:00:0 ...