关于这道题请移步kuangbin爷的blog:http://www.cnblogs.com/kuangbin/archive/2013/07/24/3210565.html

感觉我一辈子也不能写出这么详细的题解.

Code:

  

/*=================================
# Created time: 2016-04-18 16:03
# Filename: hdu4609.cpp
# Description:
=================================*/
#define me AcrossTheSky&HalfSummer11
#include <cstdio>
#include <cmath>
#include <ctime>
#include <string>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm> #include <set>
#include <stack>
#include <queue>
#include <vector> #define lowbit(x) (x)&(-x)
#define Abs(x) ((x) > 0 ? (x) : (-(x)))
#define FOR(i,a,b) for((i)=(a);(i)<=(b);(i)++)
#define FORP(i,a,b) for(int i=(a);i<=(b);i++)
#define FORM(i,a,b) for(int i=(a);i>=(b);i--)
#define ls(a,b) (((a)+(b)) << 1)
#define rs(a,b) (((a)+(b)) >> 1)
#define getlc(a) ch[(a)][0]
#define getrc(a) ch[(a)][1] #define maxn 300005
#define maxm 100005
#define INF 1070000000
using namespace std;
typedef long long ll;
typedef unsigned long long ull; template<class T> inline
void read(T& num){
num = 0; bool f = true;char ch = getchar();
while(ch < '0' || ch > '9') { if(ch == '-') f = false;ch = getchar();}
while(ch >= '0' && ch <= '9') {num = num * 10 + ch - '0';ch = getchar();}
num = f ? num: -num;
}
int outs[100];
template<class T> inline
void write(T x){
if (x==0) {putchar('0'); putchar(' '); return;}
if (x<0) {putchar('-'); x=-x;}
int num=0;
while (x){ outs[num++]=(x%10); x=x/10;}
FORM(i,num-1,0) putchar(outs[i]+'0'); putchar(' ');
}
/*==================split line==================*/
const double pi=acos(-1);
struct cpx{
double x,y;
cpx(double a=0,double b=0):x(a),y(b){}
}f[maxn],g[maxn],eps[maxn],inv_eps[maxn];
inline cpx operator +(cpx a,cpx b){return cpx(a.x+b.x,a.y+b.y);}
inline cpx operator -(cpx a,cpx b){return cpx(a.x-b.x,a.y-b.y);}
inline cpx operator *(cpx a,cpx b){return cpx(a.x*b.x-a.y*b.y,a.x*b.y+a.y*b.x);}
inline cpx conj(cpx a){return cpx(a.x,-a.y);}
inline void geteps(ll n){
double angle=2*pi/n;
FORP(i,0,n) { double t=angle*i; eps[i]=cpx(cos(t),sin(t)); inv_eps[i]=conj(eps[i]);}
}
inline void fft(ll n,cpx *buffer,cpx *eps){
for (ll i=0,j=0;i<n;i++){
if (i<j) swap(buffer[i],buffer[j]);
for (ll l=n>>1;(j^=l)<l;l>>=1);
}
for (ll i=2;i<=n;i<<=1){
ll m=i>>1;
for (ll j=0;j<n;j+=i)
for (ll k=0;k<m;k++){
cpx z=buffer[j+m+k]*eps[n/i*k];
buffer[j+m+k]=buffer[j+k]-z;
buffer[j+k]=buffer[j+k]+z;
}
}
}
ll a[100005],num[maxn];
int main(){
int cas; read(cas);
while (cas--){
//f.clear(); g.clear();
memset(f,0,sizeof(f)); //memset(g,0,sizeof(g));
int n; read(n);
ll maxa=0;
FORP(i,1,n) {read(a[i]); maxa=max(maxa,a[i]); f[a[i]].x++;} //g[a[i]]=f[a[i]];}
ll k=1;
while(k<=maxa) k<<=1;
k<<=1;
geteps(k);
fft(k,f,eps); //fft(k,g,eps);
FORP(i,0,k-1) f[i]=f[i]*f[i];
fft(k,f,inv_eps);
FORP(i,0,k-1) f[i].x/=(double)k;
//memset(num,0,sizeof(num));
FORP(i,0,k-1) num[i]=trunc(f[i].x+0.5);
FORP(i,1,k-1) if (num[i]<0) printf("flag\n");
FORP(i,1,n) num[a[i]+a[i]]--;
FORP(i,0,k-1) num[i]/=2;
FORP(i,1,k-1) num[i]+=num[i-1];
sort(a+1,a+1+n);
ll ans=0;
for(ll i=1;i<=n;i++)
ans=ans+num[k-1]-num[a[i]]-(n-1)-(i-1)*(n-i)-(n-i)*(n-i-1)/2;
ll down=(ll)n*(n-1)*(n-2)/6;
printf("%.7lf\n",(double)ans/down);
}
}

HDU4609 & FFT的更多相关文章

  1. HDU-4609(FFT/NTT)

    HDU-4609(FFT/NTT) 题意: 给出n个木棒,现从中不重复地选出3根来,求能拼出三角形的概率. 计算合法概率容易出现重复,所以建议计算不合法方案数 枚举选出的最大边是哪条,然后考虑剩下两条 ...

  2. HDU4609 FFT+组合计数

    HDU4609 FFT+组合计数 传送门:http://acm.hdu.edu.cn/showproblem.php?pid=4609 题意: 找出n根木棍中取出三根木棍可以组成三角形的概率 题解: ...

  3. [HDU4609]3-idiots(生成函数+FFT)

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

  4. HDU4609 3-idiots(母函数 + FFT)

    题目 Source http://acm.hdu.edu.cn/showproblem.php?pid=4609 Description King OMeGa catched three men wh ...

  5. HDU4609 计数问题+FFT

    题目大意: 给出n(1e5)条线段(长度为整数,<=1e5),求任取3条线段能组成一个三角形的概率. 用cnt[i]记录长度为i的线段的个数,通过卷积可以计算出两条线段长度之和为i的方案数sum ...

  6. 3-idiots hdu4609 母函数+FFT 组合数学题

    http://acm.hdu.edu.cn/showproblem.php?pid=4609 题意:1e5个数,求取三个数能形成三角形的概率. 题解(这怎么会是fft入门题QAQ): 概率的算法就是三 ...

  7. 【hdu4609】 3-idiots FFT

    题外话:好久没写blog了啊-- 题目传送门 题目大意:给你m条长度为ai的线段,求在其中任选三条出来,能构成三角形的概率.即求在这n条线段中找出三条线段所能拼出的三角形数量除以$\binom{m}{ ...

  8. HDU4609:3-idiots(FFT)

    Description Input Output Sample Input Sample Output Solution 题意:给你$n$根木棍,问你任选三根能构成三角形的概率是多少. 写挂sb细节心 ...

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

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

随机推荐

  1. Html中<a>标签的样式的设置

    html中<a>标签的样式的设置.. ------------------------ <html> <head> <title>这是网页选项卡的名称& ...

  2. DiskFileItemFactory类的使用

      将请求消息实体中的每一个项目封装成单独的DiskFileItem (FileItem接口的实现) 对象的任务由 org.apache.commons.fileupload.FileItemFact ...

  3. centos7删除自带openjdk

    一些开发版的centos会自带jdk,我们一般用自己的jdk,把自带的删除.先看看有没有安装java -version [root@java-test-01 ~]# java -version ope ...

  4. 数据存储_ SQLite (1)

    一.SQL语句 如果要在程序运行过程中操作数据库中的数据,那得先学会使用SQL语句 1.什么是SQL SQL(structured query language):结构化查询语言 SQL 是一种对关系 ...

  5. PHP读写文件

    一:读取文件 例1: $xml = ""; //打开文件 $f = fopen('http://app.eyuebus.com/Public/apk/version.xml', ' ...

  6. PHP安装模式cgi、fastcgi、php_mod比较

    先了解一下普通cgi的工作流程: web server收到用户请求,并把请求提交给cgi程序,cgi程序根据请求提交的参数作相应处理,然后输出标准的html语句返回给web server,web se ...

  7. libevent在windows平台下通过vs进行编译

    1.vs中新建一个静态库项目 2.配置头文件目录,将./compat../include../WIN32-Code三个目录添加到文件目录中 3.用记事本打开Makefile.nmake文件,可以看到里 ...

  8. 【学习笔记】ionic 学习之环境搭建

    初学ionic ,后面会把学习的点滴和踩到坑全部记录下来 1.环境 安装node.js 官网地址:https://nodejs.org/en/ 下载安装包安装.自己记住自己的安装路径哦 安装完成后我们 ...

  9. iOS 判断纯汉字,还是是否含有汉字

    参考:http://www.jianshu.com/p/18cc511b5828 在一些特定的情况下,我们需要判断字符串是否为纯汉字,还是只是含有汉字的情况.我把它写成了一个分类,方便大家使用 NSS ...

  10. AngularJS多模块开发

    angularJS中的多模块开发是指多个module模块开发,步骤为: 1. 确定主模块    var app=angular.module('myApp',[]); 2. 其他的子模块添加到主模块后 ...