HDU 4609 3-idiots (FFT-快速傅立叶变换)
【题意】给定N个树枝,求从中取出三个可以围成三角形的概率
【思路】
2013多校训练第一场比赛1010题。
一开始就想到了O(n^2)枚举前两个树枝和的算法,赛后群里大牛说计算所有两个树枝和的情况可以用FFT在O(NlogN)时间内做到,于是剩下的问题就便简单了,于是就滚去学FFT了~
FFT可以在O(NlogN)时间内计算点值将多项式A = a1•x1 + a2•x2 + …… + an•xn, B = b1•x1 + b2•x2 + …… + bn•xn由系数表示法( 系数向量a = (a1, a2, ……, an) )转换成点值表示法从而可以在O(N)时间内计算出多项式乘积然后再在O(NlogN)时间内把乘积的点值表示法转换成系数表示法(这一过程叫插值),达到加速多项式乘法的作用。
那么我们怎么通过多项式乘法来快速计算出两个数组任意一项和的结果呢?应该想到乘法和加法间的联系:指数。所以我们可以令数组中的项为多项式的系数,比如(1, 3, 3, 4)就可以表示成P = 1*x1+2*x3+1*x4,这样两个多项式的乘积对应指数的系数就表示两个多项式指数和为该数的方案数。
在此题中我们令num[i]表示树枝长度为i的树枝个数,我们把它当作多项式的系数向量,对自身做一次乘法,结果的系数向量就对应和为某个长度的个数。
举个例子,num = {0 1 0 2 1}, 则num * num = {0 0 1 0 4 2 4 4 1},
这个结果的意义如下:
从{1 3 3 4}取一个数,从{1 3 3 4}再取一个数
取两个数和为 2 的取法是一种:1+1
和为 4 的取法有四种:1+3, 1+3 ,3+1 ,3+1
和为 5 的取法有两种:1+4 ,4+1;
和为 6的取法有四种:3+3,3+3,3+3,3+3,3+3
和为 7 的取法有四种: 3+4,3+4,4+3,4+3
和为 8 的取法有 一种:4+4
当然这样的结果是任意两个数相加,而题目中要求本身不能重复使用,所以要把取同一个的组合的情况删掉:for (int i = 0; i < n; i ++) num[a[i]+a[i]] --;
然后我们统计方案采用无序的组合方法(即1\2\3和3\2\1等价),并假定x1<x2<x3,所以在总方案中要减一半:for (int i = 1; i < maxn; i ++) num[i] /= 2;
最后对数组求前缀和就求出了所有x+y<=z的情况:for (int i = 1; i < maxn; i ++) sum[i] = sum[i-1] + num[i];
枚举第三个树枝的长度把结果加起来计算概率,用1减后就是最后的结果了。
重要:这里为什么要先求x+y<=z而不直接求x+y>z呢?因为前面说了我们计算过程中是按照组合统计的,并且假定第三个树枝数最大,那么统计x+y>z的方案就比较麻烦,因为需要去除掉z<x\y的情况,但是统计x+y<=z就简单了~因为这样z必定大于x\y。
【代码】
这道题内存和时间卡的紧,FFT要用迭代的算法,递归算法会超内存。
#include
#include
#include
#include
#include
#include
#define MID(x,y) ((x+y)/2)
#define mem(a,b) memset(a,b,sizeof(a))
using namespace std;const double eps = 1e-8;
const double Pi = acos(-1.0);
struct complex{
double r,i;
complex(double _r = 0,double _i = 0){
r = _r; i = _i;
}
complex operator +(const complex &b){
return complex(r+b.r,i+b.i);
}
complex operator -(const complex &b){
return complex(r-b.r,i-b.i);
}
complex operator *(const complex &b){
return complex(r*b.r-i*b.i,r*b.i+i*b.r);
}
};
struct FastFourierTransform{
inline int dcmp(double a){ if (aeps); }
void ReverseBits(complex *y, int len){
int i,j,k;
for(i = 1, j = len>>1; i > 1;
while(j >= k){
j -= k;
k >>= 1;
}
if(j nb) ? na : nb;
nc = 1;
while(nc 0 && dcmp(c[nc-1]) == 0; nc--);
// 这句加上时间还多了,不知道算不算优化……
delete ya; delete yb; delete yc;
}
//Convolution: r(k) = sigma(a[i]*b[i-k]){i=0~n-1}
//N must be power of 2
void Convolution(int *a, int *b, int *r, int n){
complex *d1 = new complex[n], *d2 = new complex[n], *y = new complex[n];
d1[0] = b[0];
int nc = 1;
while(ncHDU 4609 3-idiots (FFT-快速傅立叶变换)的更多相关文章
- FFT(快速傅立叶变换):HDU 1402 A * B Problem Plus
Calculate A * B. Input Each line will contain two integers A and B. Process to end of file. Note: th ...
- FFT快速傅立叶变换的工作原理
实数DFT,复数DFT,FFTFFT是计算DFT的快速算法,但是它是基于复数的,所以计算实数DFT的时候需要将其转换为复数的格式,下图展示了实数DFT和虚数DFT的情况,实数DFT将时域中N点信号转换 ...
- spoj VFMUL FFT快速傅立叶变换模板题
题意:求两个数相乘. 第一次写非递归的fft,因为一个数组开小了调了两天TAT. #include<iostream> #include<cstring> #include&l ...
- FFT快速傅立叶变换
//最近突然发现博客园支持\(\rm\LaTeX\),非常高兴啊! 话说离省选只有不到五天了还在学新东西确实有点逗…… 切到正题,FFT还是非常神奇的一个东西,能够反直觉地把两个多项式相乘的时间复杂度 ...
- FFT快速傅立叶变换:解析wav波频图、Time Domain、Frequency Domain
您好,此教程将教大家使用scipy.fft分析wav文件的波频图.Time Domain.Frequency Domain. 实际案例:声音降噪,去除高频. 结果: 波频图: Time Domain:
- 离散傅立叶变换与快速傅立叶变换(DFT与FFT)
自从去年下半年接触三维重构以来,听得最多的词就是傅立叶变换,后来了解到这个变换在图像处理里面也是重点中的重点. 本身自己基于高数知识的理解是傅立叶变换是将一个函数变为一堆正余弦函数的和的变换.而图像处 ...
- 快速傅立叶变换(FFT)算法
已知多项式f(x)=a0+a1x+a2x2+...+am-1xm-1, g(x)=b0+b1x+b2x2+...+bn-1xn-1.利用卷积的蛮力算法,得到h(x)=f(x)g(x),这一过程的时间复 ...
- $\mathcal{FFT}$·$\mathcal{Fast \ \ Fourier \ \ Transformation}$快速傅立叶变换
\(2019.2.18upd:\) \(LINK\) 之前写的比较适合未接触FFT的人阅读--但是有几个地方出了错,大家可以找一下233 啊-本来觉得这是个比较良心的算法没想到这么抽搐这个算法真是将一 ...
- BZOJ 2194 快速傅立叶变换之二 | FFT
BZOJ 2194 快速傅立叶变换之二 题意 给出两个长为\(n\)的数组\(a\)和\(b\),\(c_k = \sum_{i = k}^{n - 1} a[i] * b[i - k]\). 题解 ...
- 快速傅立叶变换(FFT)
多项式 系数表示法 设\(f(x)\)为一个\(n-1\)次多项式,则 \(f(x)=\sum\limits_{i=0}^{n-1}a_i*x_i\) 其中\(a_i\)为\(f(x)\)的系数,用这 ...
随机推荐
- java多线程状态转换
http://www.mamicode.com/info-detail-517008.html 相关资料链接 我觉得下面这张图总结的很好
- 【BZOJ】【1833】【ZJOI2010】count 数字计数
数位DP Orz iwtwiioi 学习了一下用记忆化搜索来捉题的新姿势……但没学会TAT,再挖个坑(妈蛋难道对我来说数位DP就是个神坑吗……sigh) //BZOJ 1833 #include< ...
- pureftpd安装配置-pureftp参数详解(一)
1. 下载 #cd /usr/local/src/ #wget ftp://ftp.pureftpd.org/pub/pure-ftpd/releases/pure-ftpd-1.0.30.tar.g ...
- EBP的妙用[无法使用ESP定律时]
1.了解EBP寄存器 在寄存器里面有很多寄存器虽然他们的功能和使用没有任何的区别,但是在长期的编程和使用 中,在程序员习惯中已经默认的给每个寄存器赋上了特殊的含义,比如:EAX一般用来做返回值,ECX ...
- gcd 最大公约数 模版!
1: #define ll long long ll gcd(ll a,ll b) { ) { return b; }else { return gcd(b % a,a); } } 2: int64 ...
- Ubuntu 启动栏添加eclipse图标
sudo gedit /usr/share/applications/eclipse.desktop [Desktop Entry] Name=Eclipse Comment=c project ma ...
- 找啊找啊找GF
P1013 找啊找啊找GF 时间: 1000ms / 空间: 131072KiB / Java类名: Main 背景 MM七夕模拟赛 描述 "找啊找啊找GF,找到一个好GF,吃顿饭啊拉拉手, ...
- 李洪强iOS开发支付集成之支付宝支付
iOS开发支付集成之支付宝支付 下载支付宝SDK 首先是开发包下载,还是比较难发现的,网上以前文章中的链接都打不开,我找了好久才找到的.最新的地址在这里(注意的是下载出来的SDK包里面并没有传说中的开 ...
- HttpServletRequest接口实例化的使用
HttpServletRequ接口的使用和jsp内置对象的request对象非常类似,request对象其实 就是HttpServletRequest接口的一个实例,不过气实例化的过程是自动的,无须自 ...
- OSSEC - Agent端查看命令
命令:/opt/ossec/bin/agent_control -h注释:/opt/为安装目录 [root@redhat rules]# /opt/ossec/bin/agent_control -h ...