快速傅里叶变化有不同的应用场景,hdu4609就比较有意思。题目要求是给n个线段,随机从中选取三个,组成三角形的概率。

初始实在没发现这个怎么和FFT联系起来,后来看了下别人的题解才突然想起来:组合计数问题可以用多项式的卷积来解决。于是将给的数据进行卷积相乘,利用FFT即可求出三角形任意两条线段组合的可能数目。

然后遍历初始数据,将其作为最长边(这里一开始也没想明白,其实就是只要最长边大于短边之和,其他两个不等式也自然可以满足)。那么理论上说比它长的所有两边组合可能都可以。当然在这里要考虑三种特殊情况:(即在两边组合数目中减去这些情况)

1.这两个边有可能一个边比最长边长,一个边小于最长边

2.其中一个边就是要选的这个边

3.两个边其实都比最长边长,这种情况要除以二

PS:G++使用的是longlong类型,C++是_int64,好久没写忘记了。

longlong在代码中间乘的运算也要加上,否则还是会出错。

#include <iostream>
#include <cmath>
#include <algorithm> //spell!
#include <string.h>
#define MAXN 400040
#define PI acos(-1.0)
using namespace std; struct complex
{
double r,i;
complex(double real=0.0,double image=0.0)
{
r=real;
i=image;
}
//以下为三种虚数运算的定义
complex operator+(const complex o)
{
return complex(r+o.r,i+o.i);
}
complex operator-(const complex o)
{
return complex(r-o.r,i-o.i);
}
complex operator*(const complex o)
{
return complex(r*o.r-i*o.i,r*o.i+i*o.r);
}
}x1[MAXN]; void bitrev(complex *y,int l) //二进制平摊反转置换 O(logn)
{
register int i,j,k;
for(i=,j=l/;i<l-;i++)
{
if(i<j) swap(y[i],y[j]); //交换互为下标反转的元素
//i<j保证只交换一次
k=l/;
while(j>=k) //由最高位检索,遇1变0,遇0变1,跳出
{
j-=k;
k/=;
}
if(j<k) j+=k;
}
}
void fft(complex *in,int n,int flag)
{
int i,j,k;
complex u,t;
bitrev(in,n);
for(int i=;i<=n;i=i*)
{
complex wn(cos((*PI*flag)/i),sin((*PI*flag)/i));//初始化单位复根
for(j=;j<n;j=j+i)
{
complex w(,);
for(k=j;k<j+i/;k++)
{
u=in[k];
t=w*in[k+i/];
in[k]=u+t;
in[k+i/]=u-t;
w=w*wn;
}
}
}
if(flag==-)
for(int i=;i<n;i++)
in[i].r=in[i].r/n;
} int a[];
long long res[MAXN];
long long sum[MAXN];
long long num[MAXN];
int main() {
int T;
scanf("%d",&T);
while(T--)
{
int n,i;
scanf("%d",&n);
memset(res,,sizeof(res));
memset(sum,,sizeof(sum));
memset(num,,sizeof(num));
for(int j=;j<n;j++)
{
scanf("%d",&a[j]);
num[a[j]]++;
}
sort(a,a+n);
for(i = ;i <=a[n-];i++)
{
x1[i].r=num[i];
x1[i].i=;
}
int expandn=;
while(expandn<*(a[n-]+))expandn=expandn*; for(i = a[n-]+;i<expandn;i++)
{
x1[i].r=;
x1[i].i=;
}
fft(x1,expandn,);
for(i=;i<expandn;i++)
x1[i]=x1[i]*x1[i];
fft(x1,expandn,-);
for(i=;i<expandn;i++)
{
res[i]=(long long)(x1[i].r+0.5);
}
//去除本身
for(i=;i<n;i++)
res[a[i]+a[i]]--;
//变为组合
for(i=;i<expandn;i++)
res[i]=res[i]/;
//求出两边之和为i的所有可能
//expandn=(a[n-1]+1)*2;
sum[]=res[];
for(i=;i<expandn;i++)
sum[i]=res[i]+sum[i-];
long long ans=;
for(i=;i<n;i++)
{
ans+=sum[expandn-]-sum[a[i]];//比长度为a[i]大的所有可能
//去除一个大于a[i],一个小于a[i]
ans=ans-(long long)(n--i)*i;
//去除一个取自己
ans=ans-(n-);
//去除取两个都大
ans=ans-(long long)(n--i)*(n--i)/;
}
long long all = (long long)n*(n-)*(n-)/;
printf("%.7lf\n",(double)ans/all);
}
}

hdu 4609

快速傅里叶变换应用之二 hdu 4609 3-idiots的更多相关文章

  1. 基于python的快速傅里叶变换FFT(二)

    基于python的快速傅里叶变换FFT(二)本文在上一篇博客的基础上进一步探究正弦函数及其FFT变换. 知识点  FFT变换,其实就是快速离散傅里叶变换,傅立叶变换是数字信号处理领域一种很重要的算法. ...

  2. 解题:HDU 4609 Three Idiots

    题面 要求组合的方法显然我们需要对桶卷积,即设$F(x)=\sum\limits_{i=1}^{maxx}x^{cnt[i]}$,然后我们初步的先把$F^2(x)$卷出来,表示选两条边.然后我们发现如 ...

  3. HDU 1402 A * B Problem Plus 快速傅里叶变换 FFT 多项式

    http://acm.hdu.edu.cn/showproblem.php?pid=1402 快速傅里叶变换优化的高精度乘法. https://blog.csdn.net/ggn_2015/artic ...

  4. [学习笔记] 多项式与快速傅里叶变换(FFT)基础

    引入 可能有不少OIer都知道FFT这个神奇的算法, 通过一系列玄学的变化就可以在 $O(nlog(n))$ 的总时间复杂度内计算出两个向量的卷积, 而代码量却非常小. 博主一年半前曾经因COGS的一 ...

  5. 「快速傅里叶变换(FFT)」学习笔记

    FFT即快速傅里叶变换,离散傅里叶变换及其逆变换的快速算法.在OI中用来优化多项式乘法. 本文主要目的是便于自己整理.复习 FFT的算法思路 已知两个多项式的系数表达式,要求其卷积的系数表达式. 先将 ...

  6. 多项式 之 快速傅里叶变换(FFT)/数论变换(NTT)/常用套路【入门】

    原文链接https://www.cnblogs.com/zhouzhendong/p/Fast-Fourier-Transform.html 多项式 之 快速傅里叶变换(FFT)/数论变换(NTT)/ ...

  7. 快速傅里叶变换(FFT)

    扯 去北京学习的时候才系统的学习了一下卷积,当时整理了这个笔记的大部分.后来就一直放着忘了写完.直到今天都腊月二十八了,才想起来还有个FFT的笔记没整完呢.整理完这个我就假装今年的任务全都over了吧 ...

  8. 研究傅里叶变换的一本好书<<快速傅里叶变换及其C程序>>

    快速傅里叶变换及其C程序 <快速傅里叶变换及其C程序>是中国科学技术大学出版社出版的.本书系统地介绍了傅里叶变换的理论和技术,内容包括傅里叶变换(FT)的定义.存在条件及其性质,离散傅里叶 ...

  9. 快速傅里叶变换(FFT)学习笔记(未完待续)

    目录 参考资料 FFT 吹水 例题 普通做法 更高大尚的做法 定义与一部分性质 系数表达式 点值表达式 点值相乘??? 卷积 复数 单位根 DFT IDFT 蝴蝶迭代优化 单位根求法 实现.细节与小优 ...

随机推荐

  1. Java发送HTTP POST请求(内容为xml格式)

    今天在给平台用户提供http简单接口的时候,顺便写了个调用的Java类供他参考.      服务器地址:http://5.0.217.50:17001/VideoSend 服务器提供的是xml格式的h ...

  2. SpringMVC静态文件(图片)访问+js访问 简单小例子

    项目文件布局: web.xml文件: <?xml version="1.0" encoding="UTF-8"?> <web-app vers ...

  3. 关于php析构函数__destruct()的问题

    1.背景:在一次输出错误信息,引入Componets\下的ErrorCode的类文件报错,报错的信息是该类找不到:然而那个类文件明明存在的阿,怎么会报错呢? 2.解决过程:看类加载器如何加载该类.通过 ...

  4. centos下卸载jdk

    链接地址:http://blog.csdn.net/shuixin536/article/details/8954011 http://sunqiusong.email.blog.163.com/bl ...

  5. Android 开发笔记 “SharePreference 数据存取”

    除了SQLite数据库外,SharedPreferences也是一种轻型的数据存储方式,它的本质是基于XML文件存储key-value键值对数据,通常用来存储一些简单的配置信息.其存储位置在/data ...

  6. Android 学习开发笔记《Android认识》

    1.          Android:2007年11月5日第一版,2009年5月豪华版,2010年HTC手机 2.          Android框架主要:应用程序.应用程序框架.函数库.运行时. ...

  7. Nginx 之六: Nginx服务器的反向代理功能

    一:Nginx作为正向代理服务器: 1.正向代理:代理(proxy)服务也可以称为是正向代理,指的是将服务器部署在公司的网关,代理公司内部员工上外网的请求,可以起到一定的安全作用和管理限制作用,正向代 ...

  8. dede修改移动文档的js

    dede后台弹框修改: 想做个类似文章列表的移动功能,弹框,然后修改成功到表 先在list.js里复制一份moveArc的方法,到archives_do.php里复制一份moveArchives的方法 ...

  9. GSAP学习笔记

    GSAP(Green Sock Animation Platform)是一个十分好用的js动画库,据说是as的精简版 以下是学习GSAP的一些笔记:貌似中文的文档不是很多 GSAP notes: tl ...

  10. 啊华北哦好咕~~(╯﹏╰)b

    http://v.qq.com/boke/page/c/h/0/c01173tzeh0.html http://v.qq.com/boke/page/r/7/x/r0117l07r7x.html ht ...