hdu 4609 3-idiots [FFT计数]【数学】
来源:互联网 发布:mac miller a妹 编辑:程序博客网 时间:2024/04/28 06:46
题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=4609
———————————————————–.
3-idiots
Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 4437 Accepted Submission(s): 1561
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
Source
2013 Multi-University Training Contest 1
———————————————————–.
题目大意:
就是跟你N个数代表长度为
解题思路:
首先考虑暴力的
就是求
所以最严重的问题就是如何求这N个数的两两相加.
这时候如果把加法换成乘法那么就可以转化为向量相乘,用FFT就可以
然后我们考虑将加法换成乘法,其实很简单,我们只要将加数代换成幂指数的指数就可以了,
我们可以用一个hash[a[i]]来记录每个大小的数都有几个
那么FFT之后的结果稍加一点简单处理就是两个不同的木棍长度加和wei
而我们要的就是这个情况数,所以就不需要在继续处理了
附本题链接
———————————————————–.
#include <bits/stdc++.h>using namespace std;#define INF (~(1<<31))#define INFLL (~(1ll<<63))#define pb push_back#define mp make_pair#define abs(a) ((a)>0?(a):-(a))#define lalal puts("*******");#define s1(x) scanf("%d",&x)#define Rep(a,b,c) for(int a=(b);a<=(c);a++)#define Per(a,b,c) for(int a=(b);a>=(c);a--)#define no puts("NO")typedef long long int LL ;typedef unsigned long long int uLL ;const int MOD = 1e9+7;const int N = 264000+5;const double eps = 1e-6;const double PI = acos(-1.0);inline int read(){ int x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f;}void fre(){ freopen("in.txt","r",stdin); freopen("out.txt","w",stdout);}/***********************************************************************/struct Complex{ double real, image; Complex(double _real, double _image){ real = _real; image = _image; } Complex(){} Complex operator + (const Complex &tmp){ return Complex(real + tmp.real, image + tmp.image); } Complex operator - (const Complex &tmp){ return Complex(real - tmp.real, image - tmp.image); } Complex operator * (const Complex &tmp){ return Complex(real*tmp.real - image*tmp.image, real*tmp.image + image*tmp.real); }};int rev(int id, int len){ int ret = 0; for(int i = 0; (1 << i) < len; i++){ ret <<= 1; if(id & (1 << i)) ret |= 1; } return ret;}Complex A[264000];void FFT(Complex *a, int len, int DFT){ for(int i = 0; i < len; i++) A[rev(i, len)] = a[i]; for(int s = 1; (1 << s) <= len; s++){ int m = (1 << s); Complex wm = Complex(cos(DFT*2*PI/m), sin(DFT*2*PI/m)); for(int k = 0; k < len; k += m){ Complex w = Complex(1, 0); for(int j = 0; j < (m >> 1); j++){ Complex t = w*A[k + j + (m >> 1)]; Complex u = A[k + j]; A[k + j] = u + t; A[k + j + (m >> 1)] = u - t; w = w*wm; } } } if(DFT == -1) for(int i = 0; i < len; i++) A[i].real /= len, A[i].image /= len; for(int i = 0; i < len; i++) a[i] = A[i]; return;}int num[100010],h[200010];Complex a[264000];LL tA[200010],sum[200010];int main(){ int _, n; while(~scanf("%d", &_)) while(_--) { scanf("%d", &n); int mx = 0; memset(h, 0, sizeof(h)); for(int i = 1; i <= n; i++) { scanf("%d", &num[i]); h[num[i]]++; } sort(num+1, num + n+1); mx = num[n]; int len = 1; while(len <= mx) len <<= 1; len <<= 1; for(int i = 0; i < len; i++) a[i] = Complex((i<=mx)?h[i]:0, 0); FFT(a, len, 1); for(int i = 0; i < len; i++) a[i] = a[i]*a[i]; FFT(a, len, -1); for(int i = 0; i <= (mx<<1); i++) tA[i] = (LL)(a[i].real + 0.5); for(int i=0;i<=n;i++) tA[num[i]<<1]--; for(int i = 0; i <= (mx<<1); i++) tA[i] >>=1; //到现在为止A[i]表示的是去两根不同的branch的长度和为i的组合种数 sum[0] = 0; for(int i = 1; i <= (mx<<1); i++) sum[i] = sum[i - 1] + tA[i]; LL ans = 0; for(int i = 1; i <= n; i++)//以第i根作为边最长的 { LL tmp = sum[(mx<<1)] - sum[num[i]];//另外两条边长度和要大于branch[i] tmp -= (LL)(n - i)*(i - 1);//另外两条一条比branch[i]长, 一条不比它长 tmp -= (LL)(n - i)*(n - i - 1) / 2;//两条都比他长 tmp -= n - 1;//另外两条的组合中包括它自己的组合 ans += tmp; } printf("%.7f\n",ans*6./n/(n - 1)/(n - 2)); } return 0;}
- hdu 4609 3-idiots [FFT计数]【数学】
- hdu 4609 3-idiots (FFT+计数)
- HDU 4609 3-idiots FFT+计数问题
- hdu 4609 3-idiots FFT 计数
- HDU 4609 3-idiots(FFT,计数)
- HDU 4609 3-idiots 计数+FFT
- [HDU 4609] 3-idiots (计数+FFT优化卷积)
- HDU 4609 3-idiots三个智障 FFT+组合计数
- HDU 4609 3-idiots FFT 求解计数问题
- HDU 4609 3-idiots(多项式计数 + FFT卷积优化)
- HDU 4609 3-idiots(FFT+组合计数)
- HDU 4609 3-idiots(组合数学+FFT)
- HDU 4609 3-idiots (FFT)
- hdu 4609 3-idiots FFT
- hdu 4609 3-idiots (FFT)
- HDU 4609 3-idiots FFT
- 【HDU】4609 3-idiots 【FFT】
- hdu 4609 3-idiots (FFT)
- NPC规约问题 - 8.20
- window tomcat集群(亲测)
- addEventListener/attachEvent兼容IE浏览器与标准浏览器
- linux打包压缩命令
- linux 下的系统服务管理
- hdu 4609 3-idiots [FFT计数]【数学】
- UIImage添加水印(Logo+文字)
- OJ用java时总出现Time Limit Exceeded原因之一
- vim 使用
- Win10下,笔记本通过网线分享无线网络
- JAVA设计模式之工厂模式(简单工厂模式+工厂方法模式+抽象工厂模式)
- ASP.NET MVC架构与实战系列之二:理解MVC路由配置
- JQuery DataTable 详解
- 集合框架_Collections工具类的概述