FFT(快速傅里叶变换):HDU 4609 3-idiots

3-idiots

Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 3560    Accepted Submission(s): 1241

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

  大家都去mod邝斌吧~

 1 #include <algorithm>
 2 #include <iostream>
 3 #include <cstring>
 4 #include <cstdio>
 5 #include <cmath>
 6 using namespace std;
 7 const int maxn=500010;
 8 const long double PI=acos(-1.0);
 9 struct complex{
10     long double r,i;
11     complex(long double r_=0.0,long double i_=0.0){
12         r=r_;i=i_;
13     }
14     complex operator +(complex &a){
15         return complex(a.r+r,a.i+i);
16     }
17     complex operator -(complex &a){
18         return complex(r-a.r,i-a.i);
19     }
20     complex operator *(complex a){
21         return complex(r*a.r-i*a.i,i*a.r+a.i*r);
22     }
23 }A[maxn];
24
25 void Rader(complex *a,int len){
26     for(int i=1,j=len>>1;i<len-1;i++){
27         if(i<j)swap(a[i],a[j]);
28         int k=len>>1;
29         while(j>=k){
30             j-=k;
31             k>>=1;
32         }
33         j+=k;
34     }
35 }
36
37 void FFT(complex *a,int len,int on){
38     Rader(a,len);
39     for(int h=2;h<=len;h<<=1){
40         complex wn(cos(-on*PI*2/h),sin(-on*PI*2/h));
41         for(int j=0;j<len;j+=h){
42             complex w(1.0,0);
43             for(int k=j;k<j+(h>>1);k++){
44                 complex x=a[k];
45                 complex y=a[k+(h>>1)]*w;
46                 a[k]=x+y;
47                 a[k+(h>>1)]=x-y;
48                 w=w*wn;
49             }
50         }
51     }
52     if(on==-1)
53         for(int i=0;i<len;i++)
54             a[i].r/=len;
55 }
56 int a[maxn];
57 long long num[maxn];
58 int main(){
59 #ifndef ONLINE_JUDGE
60     //freopen("","r",stdin);
61     //freopen("","w",stdout);
62 #endif
63     int T,n,len=1;
64     scanf("%d",&T);
65     while(T--){
66         scanf("%d",&n);
67         memset(A,0,sizeof(A));
68         memset(num,0,sizeof(num));
69         while(len<=200000)len<<=1;
70         for(int i=1;i<=n;i++)
71             scanf("%d",&a[i]);
72         sort(a+1,a+n+1);len=1;
73         while(len<=a[n]*2)len<<=1;
74         for(int i=1;i<=n;i++)
75             A[a[i]].r++;
76         FFT(A,len,1);
77         for(int i=0;i<len;i++)
78             A[i]=A[i]*A[i];
79         FFT(A,len,-1);
80         for(int i=0;i<len;i++)
81             num[i]=(long long)(A[i].r+0.5);
82         for(int i=1;i<=n;i++)
83             num[a[i]<<1]--;
84         for(int i=0;i<len;i++)
85             num[i]>>=1;
86         for(int i=1;i<len;i++)
87             num[i]+=num[i-1];
88         long long cnt=0;
89         for(int i=1;i<=n;i++){
90             cnt+=num[len-1]-num[a[i]];
91             cnt-=(long long)(n-i)*(i-1);
92             cnt-=n-1;
93             cnt-=(long long)(n-i)*(n-i-1)/2;
94         }
95         long long tot=((long long)n*(n-1)*(n-2))/6;
96         printf("%.7lf\n",1.0*cnt/tot);
97     }
98     return 0;
99 }
时间: 2024-12-17 06:31:42

FFT(快速傅里叶变换):HDU 4609 3-idiots的相关文章

准零基础搞懂FFT快速傅里叶变换及其实现程序(二)

上一篇文章我们了解了DFT的原理,FFT是基于DFT的更适合计算机运算的算法,本文我们就正式开始学习FFT的原理. 首先我么先来宏观的看一下FFT.如果我们把整个FFT的算法看成一个黑盒子的话,那么它的输入就是时间波形信号,比如声音波形(横轴为时间,纵轴为振幅).外什么FFT要比DFT速度更快呢?下面(图1)解释了FFT和DFT的(对于计算机的)算法复杂度 图1 从上面的数学表达式可以看出,一个1024采样点的FFT比DFT块了102.4倍.如果傅里叶变换的数量级更大,FFT的速度优势会更明显.

FFT —— 快速傅里叶变换

问题: 已知A[], B[], 求C[],使: 定义C是A,B的卷积,例如多项式乘法等. 朴素做法是按照定义枚举i和j,但这样时间复杂度是O(n2). 能不能使时间复杂度降下来呢? 点值表示法: 我们把A,B,C看作表达式. 即: A(x)=a0 + a1* x + a2 * x2 +... 将A={(x1,A(x1)), (x2,A(x2)), (x3,A(x3))...}叫做A的点值表示法. 那么使用点值表示法做多项式乘法就很简单了:对应项相乘. 那么,如何将A和B转换成点值表示法,再将C转

【Delphi】如何在三轴加速器的频谱分析中使用FFT(快速傅里叶变换)算法

关于傅里叶变换的作用,网上说的太过学术化,且都在说原理,已经如何编码实现,可能很多人有个模糊影响,在人工智能,图像识别,运动分析,机器学习等中,频谱分析成为了必备的手段,可将离散信号量转换为数字信息进行归类分析. 今天这里将的不是如何实现,而是如何使用傅里叶变换 但频谱分析中,涉及到的信号处理知识对大部分软件开发的人来说,太过于晦涩难懂,傅里叶变换,拉普拉斯,卷积,模相,实数,虚数,复数,三角函数等等,已经能让软件工程师望而却步,造成懂知识的人无法开发,懂开发的人无法分析,而同时具备两种技能的人

浅谈FFT(快速傅里叶变换)

本文主要简单写写自己学习FFT的经历以及一些自己的理解和想法. FFT的介绍以及入门就不赘述了,网上有许多相关的资料,入门的话推荐这篇博客:FFT(最详细最通俗的入门手册),里面介绍得很详细. 为什么要学习FFT呢?因为FFT能将多项式乘法的时间复杂度由朴素的$O(n^2)$降到$O(nlogn)$,这相当于能将任意形如$f[k]=\sum\limits _{i+j=k}f[i]*f[j]$的转移方程的计算在$O(nlogn)$的时间内完成.因此对于想要进阶dp的同学来说,FFT是必须掌握的技能

FFT快速傅里叶变换

摘自:https://www.cnblogs.com/RabbitHu/p/FFT.html 快速傅里叶变换(FFT)是一种能在O(nlogn)O(nlog?n)的时间内将一个多项式转换成它的点值表示的算法. 点值表示:设A(x)是一个n−1次多项式,那么把n个不同的x代入,会得到n个y.这n对(x,y)唯一确定了该多项.由多项式可以求出其点值表示,而由点值表示也可以求出多项式. 设有两个n−1次多项式A(x)和B(x)),我们的目标是——把它们乘起来.普通的多项式乘法是O(n^2),但有趣的是

【bzoj2179】FFT快速傅里叶变换(优化高精度乘法)

#include<bits/stdc++.h> using namespace std; #define pi acos(-1) typedef complex<double> C; const int N=201100; int n,m,l,r[N],ans[N]; C a[N],b[N]; char s[N],t[N]; void fft(C *a,int f){ for(int i=0;i<n;++i) if(r[i]>i) swap(a[i],a[r[i]]);

【模板】FFT快速傅里叶变换

1 struct Complex{ 2 double x, y; 3 inline Complex(double xx=0, double yy=0){ 4 x=xx; y=yy; 5 } 6 inline Complex operator + (Complex a){ 7 return Complex(x+a.x, y+a.y); 8 } 9 inline Complex operator - (Complex a){ 10 return Complex(x-a.x, y-a.y); 11 }

FFT 快速傅里叶变换

这个东西很神奇,看了半天网上的解释和课件,研究了很长时间,算是大概明白了它的原理. 话不多说先上图. 我们要求的h(x)=f(x)*g(x),f(x)=Σai*x^i,g(x)=Σbi*x^i. 朴素求复杂度是n2的,但一个x次多项式在平面上可以由x+1个点唯一插值表示,所以我们可以先用求出x+1个点(xi,f(xi))和(xi,g(xi)),再求出(xi,f(xi)*g(xi)),就可以反解出    h(x)的表达式. 那么我们需要在nlogn的时间内干完这两步,首先xi的取值需要特殊取,令x

快速傅里叶变换FFT

快速傅里叶变换FFT DFT是信号分析与处理中的一种重要变换.但直接计算DFT的计算量与变换区间长度N的平方成正比,当N较大时,计算量太大,直接用DFT算法进行谱分析和信号的实时处理是不切实际的. 1.直接计算DFT 长度为N的有限长序列x(n)的DFT为: 2.减少运算量的思路和方法 思路:N点DFT的复乘次数等于N2.把N点DFT分解为几个较短的DFT,可使乘法次数大大减少.另外,旋转因子WmN具有周期性和对称性. (考虑x(n)为复数序列的一般情况,对某一个k值,直接按上式计算X(k)值需

hdu 4609 3-idiots 【FFT快(gui)速傅立叶变换】

FFT实现起来挺复杂的,开始用vector,结果发现空间超了,换成数组还是超,删掉了几个后又超时了 sin cos 函数调用次数太多了,改成乘法,还是超时 最后把FFT里的除法运算和模运算优化了一下,终于过了,排的老后面 坑,3843MS,一看时间最少的只有671MS,我都怀疑这是不是同一个算法..为毛差距这么大 #pragma comment(linker, "/STACK:102400000,102400000") #include<iostream> #include