HDU 4609 快速傅里叶变换
来源:互联网 发布:手机p正装照软件 编辑:程序博客网 时间:2024/06/05 13:23
题目链接
题意:已知n条边的长度,任取三条不同的边能够组成三角形的概率。
很经典的FFT
如果已知任意两条边的和的情况,那么枚举第三条边可以在
难点便在于如果枚举两条边求和,其复杂度是不可承受的
考虑用FFT优化该过程。
构造多项式,
类似于生成函数求方案数的思想。
该多项式与自身相乘便能得出任意两条边的组合情况。
此时应减去取了两条相同边的方案数,另外因为取边没有顺序,(边1+边2)与(边2+边1)是同一种情况,故每个系数应该除2。
然后处理一个前缀和就能快速求解啦~。
#include<cstdio>#include<cstdlib>#include<algorithm>#include<cstring>#include<cmath>using namespace std;typedef long long ll;const double pi = acos(-1.0);class comp{public: double r,i; comp(double _r = 0,double _i = 0){r = _r;i = _i;} comp operator+(const comp x){return comp(r+x.r,i+x.i);} comp operator-(const comp x){return comp(r-x.r,i-x.i);} comp operator*(const comp x){return comp(r*x.r-i*x.i,r*x.i+i*x.r);}};void FFT(comp a[],int n,int t){ for(int i=1,j=0; i<n-1 ;i++){ for(int s=n;j^=s>>=1,~j&s;); if(i<j) swap(a[i],a[j]); } for(int d=0;(1<<d)<n ;d++){ int m = 1<<d,m2 = m<<1; double o = pi/m*t;comp _w(cos(o),sin(o)); for(int i=0 ;i<n ;i+=m2){ comp w(1,0); for(int j=0 ;j<m ;j++){ comp &A = a[i+j+m],&B = a[i+j],t = w*A; A = B-t;B = B+t;w = w*_w; } } } if(t==-1) for(int i=0 ;i<n ;i++) a[i].r/=n;}const int A = 1e5 + 10;comp x[A<<2];ll Ans[A<<2],all,ans;int cnt[A],a[A],len,m;void input(){ scanf("%d",&m); memset(cnt,0,sizeof(cnt)); for(int i=0 ;i<m ;i++){ scanf("%d",&a[i]); cnt[a[i]]++; } sort(a,a+m); len = a[m-1] + 1; all = 1LL*m*(m-1)*(m-2)/6;}void solve(){ int n = 1; while(n < 2*len) n<<=1; for(int i=0 ;i<len ;i++) x[i] = comp(cnt[i],0); for(int i=len;i<n ;i++) x[i] = comp(0,0); FFT(x,n,1); for(int i=0 ;i<n ;i++) x[i] = x[i]*x[i]; FFT(x,n,-1); for(int i=0 ;i<n ;i++) Ans[i] = (ll)(x[i].r + 0.5);n = 2*a[m-1]; for(int i=0 ;i<m ;i++) Ans[2*a[i]]--; //排除取相同边的情况 for(int i=0 ;i<=n;i++) Ans[i] /= 2; //排除取边顺序不同的重复情况 for(int i=1 ;i<=n;i++) Ans[i] += Ans[i-1]; //处理前缀和 ans = 0; for(int i=0 ;i<m ;i++){ ans += Ans[n] - Ans[a[i]]; ans -= 1LL*i*(m-i-1); //减去一大一小的情况 ans -= 1LL*(m-i-1)*(m-i-2)/2; //减去两大的情况 ans -= 1LL*(m-1); //减去含自身的不合法情况 } printf("%.7f\n",1.0*ans/all);}int main(){ int T; scanf("%d",&T); while(T--){ input(); solve(); } return 0;}
阅读全文
0 0
- HDU 4609 快速傅里叶变换
- HDU 4609 快速傅里叶变换
- hdu 4609(快速傅里叶变换)
- hdu 4609 3-idiots 快速傅里叶变换/FFT
- HDU 1402 快速傅里叶变换
- HDU 1402 快速傅里叶变换FFT
- 快速傅里叶变换-快速傅里叶变换
- 快速傅里叶变换
- 快速傅里叶变换
- 快速傅里叶变换
- 快速傅里叶变换
- 快速傅里叶变换
- 快速傅里叶变换
- 快速傅里叶变换
- 快速傅里叶变换
- 快速傅里叶变换
- 快速傅里叶变换
- 快速傅里叶变换
- CXF部署到weblogic
- Android进程保活招式大全
- Visual Sutdio 安装reshaper免激活
- Activity,Fragment互相调用几种写法,
- Maximum Product of Three Numbers
- HDU 4609 快速傅里叶变换
- 自学struts时,javax.servlet.ServletException: java.lang.NullPointerException
- 关于Installation error: Unknown failure错误
- 压缩感知测量矩阵构造方法研究
- storm集群部署和配置过程详解
- 【怎样写代码】对象克隆 -- 原型模式(一):问题案例
- node.js将图片数据转换成base64位的字符串
- VMWare Player+Fedroa24 部署DPDK运行报错问题解决方法
- 导入SpringMVC项目报错