快速傅里叶变化有不同的应用场景,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. nopcommerce插件使用

    nopcommerce是国外用.net开发的电商b2c开源项目,主要涉及技术包括了ef+mvc. 今天主要分析nop的插件机制. 什么是插件?插件是预先开发好的可以独立运行的功能模块,把单独的功能模块 ...

  2. [Git]自译《Git版本控制管理》——1.介绍(二)_Git诞生

    译者前言:      本系列译文为作者利用业余时间翻译,有些疏漏与翻译不到位的地方敬请谅解.      不过也很希望各位读者能给出中肯的建议.      方括号的注释,如[1][2]为译者注.     ...

  3. php基本框架

  4. Mac平台编译mupdf-qt的开源项目

    How to compile mupdf-qt Compile on Linux Install tools and thirdparty libraries You should install s ...

  5. 一个ShellExecute的超全说明(www.phidels.com这个网站很多内容)

    I. Introduction / Déclaration ShellExecute fait partie des innombrables fonctions de l'API Windows ; ...

  6. 安卓开发37:自定义的HorizontalScrollView类,使其pageScroll的时候焦点不选中

    自定义一个HorizontalScrollView类,主要为了让这个HorizontalScrollView不能鼠标点击,不能左右按键,并且没有焦点. public class ImageMoveHo ...

  7. python:利用asyncio进行快速抓取

    web数据抓取是一个经常在python的讨论中出现的主题.有很多方法可以用来进行web数据抓取,然而其中好像并没有一个最好的办法.有一些如scrapy这样十分成熟的框架,更多的则是像mechanize ...

  8. ExtJS4.2 - 从 Hello World 到 自定义组件 -01 (为爱女伊兰奋斗)

    ExtJS4.2 - 从 Hello World 到 自定义组件 - 01 经验.概述.项目搭建.国际化.HelloWorld.布局 —— 为爱女伊兰而奋斗 ——少走弯路,简单才是王道 1. 写在前面 ...

  9. [Swust OJ 249]--凸包面积

        题目链接:    http://acm.swust.edu.cn/problem/0249/   麦兜是个淘气的孩子.一天,他在玩钢笔的时候把墨水洒在了白色的墙上.再过一会,麦兜妈就要回来了, ...

  10. Tomcat 内存设置

    大型项目或者使用了SSH 的话, Tomcat 可能会报 java.lang.OutOfmemoryError: PermGen Space Windows: 在 bin/catlina.bat 最上 ...