FFT-hdu题目练习
网上FFT的讲解和板子有很多,所以直接放题目
hdu1402 http://acm.hdu.edu.cn/showproblem.php?pid=1402
/* problem:大整数乘法 solution:FFT
两个n-1阶多项式的乘积表示为 a0*x^0 + a1*x^1 + ... + a(2n-2)*x^(2n-2)
FFT可以O(nlogn)求出系数 a0, a1... a(2n-2)
10进制整数x可以表示成 a0*10^0 + a1*10^1 + a2*10^2 + ...
因此可以使用FFT求出其结果 */
#include <bits/stdc++.h> using namespace std; const int maxn = ; const double pi = acos(-1.0); typedef complex<double> dob; int n, m, len1, len2, N, L, R[maxn], c[maxn]; dob a[maxn], b[maxn]; char s1[maxn], s2[maxn]; void fft(dob *A, int f) {
for(int i = ;i < n;i ++)
if(i < R[i])
swap(A[i], A[R[i]]);
for(int i = ;i < n;i <<= ) {
dob wn(cos(pi / i), sin(f * pi / i)), x, y;
for(int j = ;j < n;j += (i << )) {
dob w(, );
for(int k = ;k < i;k ++, w *= wn) {
x = A[j + k], y = w * A[i + j + k];
A[j + k] = x + y;
A[i + j + k] = x - y;
}
}
}
} int main() {
while(~scanf("%s %s", s1, s2)) {
len1 = n = strlen(s1);
len2 = m = strlen(s2);
m += n, L = ;
for(n = ;n <= m;n <<= ) L ++;
for(int i = ;i < len1;i ++)
a[i] = s1[len1 - - i] - '';
for(int i = len1;i < n;i ++)
a[i] = ;
for(int i = ;i < len2;i ++)
b[i] = s2[len2 - - i] - '';
for(int i = len2;i < n;i ++)
b[i] = ;
memset(c, , sizeof c);
for(int i = ;i < n;i ++)
R[i] = (R[i >> ] >> ) | ((i & ) << (L - ));
fft(a, ), fft(b, );
for(int i = ;i <= n;i ++)
a[i] *= b[i];
fft(a, -), N = ;
for(int i = ;i <= m;i ++) {
c[i] += int(a[i].real() / n + 0.5);
if(c[i] > ) c[i + ] += c[i] / , c[i] %= ;
if(c[i] > ) N = i;
}
for(int i = N;~i;i --)
printf("%d", c[i]);
puts("");
}
return ;
}
hdu4609 http://acm.hdu.edu.cn/showproblem.php?pid=4609
/* problem:给定n个长度为ai的木棍
求,任选三个使其能够组成三角形的概率 solution:
ai <= 1e5,先统计c[i]代表长度为i的木棍有多少个
对c做卷积,即使用FFT求出 rep(i,0,1e5) rep(j,0,1e5) d[i+j]+=c[i]*c[j] 的d数组
d[i]即代表选出两个木棍长度之和为i的方案数
去除重复,减去使用了同一木棍两次的,i+j与j+i应为同一方案,所以rep(i,0,2e5) d[i]/=2
现在d[i]已经可以表示选出两个不同木棍长度之和为i的不同方案数了 接下来对木棍长度ai从小到大排序,对d做前缀和sd
枚举最长边为第i根木棍,则另外两条边长度之和>ai,ans+=sd[2e5]-sd[ai]
这些方案里需要去除一些不满足要求(ai为最长边)的
1.另外两条边两条均>ai,ans-=(n-i)*(n-i-1)/2
2.另外两条边一条>ai,一条<ai,ans-=(n-i)*(i-1)
3.另外两条边一条=ai,另一条随意,ans-=n-1 */
#include <bits/stdc++.h> using namespace std; const int maxn = ; const double pi = acos(-1.0); typedef long long ll; typedef complex<double> dob; int T, N, n, r, L, R[maxn], X[maxn]; dob a[maxn]; ll ans, b[maxn]; void fft(dob *A, int f) {
for(int i = ;i < N;i ++)
if(i < R[i])
swap(A[i], A[R[i]]);
for(int i = ;i < N;i <<= ) {
dob wn(cos(pi / i), sin(f * pi / i)), x, y;
for(int j = ;j < N;j += (i << )) {
dob w(, );
for(int k = ;k < i;k ++, w *= wn) {
x = A[j + k], y = w * A[i + j + k];
A[j + k] = x + y;
A[i + j + k] = x - y;
}
}
}
} int main() {
for(scanf("%d", &T);T --;) {
scanf("%d", &n), ans = r = L = ;
memset(b, , sizeof b);
for(int i = ;i <= n;i ++) {
scanf("%d", &X[i]);
r = max(r, X[i]);
b[X[i]] ++;
}
for(N = ;N <= (r + ) * ;N <<= ) L ++;
for(int i = ;i < N;i ++) a[i] = b[i];
for(int i = ;i < N;i ++)
R[i] = (R[i >> ] >> ) | ((i & ) << (L - ));
fft(a, );
for(int i = ;i < N;i ++)
a[i] *= a[i];
fft(a, -);
for(int i = ;i < N;i ++)
b[i] = ll(a[i].real() / N + 0.5);
for(int i = ;i <= n;i ++)
b[X[i] * ] --;
for(int i = ;i < N;i ++)
b[i] >>= ;
for(int i = ;i < N;i ++)
b[i] += b[i - ];
sort(X + , X + n + ), b[N] = b[N - ];
for(int i = ;i <= n;i ++) {
ans += b[N] - b[X[i]];
ans -= 1ll * (i - ) * (n - i);
ans -= (n - );
ans -= 1ll * (n - i) * (n - i - ) / ;
}
printf("%.7f\n", 1.0 * ans / (1ll * n * (n - ) * (n - ) / ));
}
return ;
}
hdu5885 http://acm.hdu.edu.cn/showproblem.php?pid=5885
/* problem:
n*m的矩形,每个点有p(i,j)
你可以选择一个点(x,y),那么在该点可以得到的价值val为
rep(i,1,n) rep(j,1,m) {
dis=(i,j)与(x,y)欧几里得距离
if(dis<R) val+=p(i,j)/(dis+1)
}
要求选取一个点,使val最大,输出val solution:
利用圆的中心对称性,使FFT之后某个点的val都在一个系数上
最终构造得到的多项式系数 M=m+R*2
A[i*M+j]=p[i][j] B[(i+R)*M+j+R]=1.0/(sqrt(i*i+j*j)+1)
val[i][j]=C[(i+R)*M+j+R] 附:这题内存限制不大,建议A,B变换完成之后,令A*=B即可,舍去C数组防止MLE */
#include <bits/stdc++.h> using namespace std; typedef long long ll; namespace FFT {
const int maxn = ;
//maxn >= (1 << k) >= n + m
const double pi = acos(-1.0); typedef complex<double> dob; int N_, L, R[maxn]; dob a[maxn], b[maxn]; void fft(dob *A, int f) {
for(int i = ;i < N_;i ++)
if(i < R[i])
swap(A[i], A[R[i]]);
for(int i = ;i < N_;i <<= ) {
dob wn(cos(pi / i), sin(f * pi / i)), x, y;
for(int j = ;j < N_;j += (i << )) {
dob w(, );
for(int k = ;k < i;k ++, w *= wn) {
x = A[j + k], y = w * A[i + j + k];
A[j + k] = x + y;
A[i + j + k] = x - y;
}
}
}
} void solve(int n, int m) {
n += m;
for(N_ = ;N_ <= n;N_ <<= ) L ++;
for(int i = ;i < N_;i ++)
R[i] = (R[i >> ] >> ) | ((i & ) << (L - ));
fft(a, ), fft(b, );
for(int i = ;i < N_;i ++)
a[i] *= b[i];
fft(a, -);
} void clean() {
for(int i = ;i < N_;i ++)
a[i] = b[i] = ;
L = ;
}
} using namespace FFT; int n, m, N, M, rr; double r; int main() {
double x, ans;
while(~scanf("%d %d %lf", &n, &m, &r)) {
rr = r, N = n + rr * , M = m + rr * , ans = ;
for(int i = ;i < n;i ++)
for(int j = ;j < m;j ++)
scanf("%lf", &a[i * M + j]);
for(int i = -rr;i <= rr;i ++)
for(int j = -rr;j <= rr;j ++) {
x = sqrt(i * i + j * j);
if(r > x) b[(i + rr) * M + j + rr] = 1.0 / (x + );
}
solve(N * M, N * M);
for(int i = ;i < n;i ++)
for(int j = ;j < m;j ++)
ans = max(ans, a[(i + rr) * M + j + rr].real() / N_);
printf("%.3f\n", ans);
clean();
}
return ;
}
持续更新
FFT-hdu题目练习的更多相关文章
- [转] HDU 题目分类
转载来自:http://www.cppblog.com/acronix/archive/2010/09/24/127536.aspx 分类一: 基础题:1000.1001.1004.1005.1008 ...
- 转载:hdu 题目分类 (侵删)
转载:from http://blog.csdn.net/qq_28236309/article/details/47818349 基础题:1000.1001.1004.1005.1008.1012. ...
- JavaScript--收藏栏添加按钮,放大hdu题目字体
觉得HDOJ的题目字体太小了,一波小操作 在收藏栏添加:添加网页->网址改为: javascript: void((function() { var element = document.get ...
- HDU题目分类
基础题: 1000.1001.1004.1005.1008.1012.1013.1014.1017.1019.1021.1028.1029.1032.1037.1040.1048.1056.1058. ...
- HDU 题目分类
转载自新浪博客,, http://blog.sina.com.cn/s/blog_71ded6bf0100tuya.html 基础题: 1000.1001.1004.1005.1008.1012.10 ...
- HDU 题目分类收集
并查集题型简单并查集1213 How Many Tables 1232 畅通工程 (杭电简单的并查集不是很多) 简单最小生成树1233 还是畅通工程 1863 畅通工程 1874 畅通工程再续 187 ...
- HDU 4609 3-idiots ——(FFT)
这是我接触的第一个关于FFT的题目,留个模板. 这题的题解见:http://www.cnblogs.com/kuangbin/archive/2013/07/24/3210565.html. FFT的 ...
- FFT初步学习小结
FFT其实没什么需要特别了解的,了解下原理,(特别推荐算法导论上面的讲解),模板理解就行了.重在运用吧. 处理过程中要特别注意精度. 先上个练习的地址吧: http://vjudge.net/vjud ...
- hdu5197 DZY Loves Orzing(FFT+分治)
hdu5197 DZY Loves Orzing(FFT+分治) hdu 题目描述:一个n*n的矩阵里填入1~n^2的数,要求每一排从前往后能看到a[i]个数(类似于身高阻挡视线那种),求方案数. 思 ...
- hdu5322 Hope(dp+FFT+分治)
hdu5322 Hope(dp+FFT+分治) hdu 题目大意:n个数的排列,每个数向后面第一个大于它的点连边,排列的权值为每个联通块大小的平方,求所有排列的权值和. 思路: 考虑直接设dp[i]表 ...
随机推荐
- 07.Javascript——入门高阶函数
高阶函数英文叫Higher-order function..JavaScript的函数其实都指向某个变量.既然变量可以指向函数,函数的参数能接收变量,那么一个函数就可以接收另一个函数作为参数,这种函数 ...
- C语言abs函数
C语言编程入门教程 - abs 函数是用来求整数的绝对值的. //函数名:abs //功 能:求整数的绝对值 //用 法:int abs(int i); //程序例: #include<stdi ...
- 前端开发神器 - Brackets
做了几年的 .Net 项目开发,后来公司转 Java 语言开发,Java 做了还没一年,公司准备前后端分离开发,而我被分到前端! Brackets是一款基于web(html+css+js)开发的web ...
- SQL Server 2008 转换为 SQL 2005 数据库 脚本生成
Tips: 本文讨论如何把数据库从SQL Server 2008版本降低到2005,因为在本地开发是以SQL Server 2008 Express Edition版本进行的,而主机提供商现在提供的M ...
- Android自定义view之仿微信录制视频按钮
本文章只写了个类似微信的录制视频的按钮,效果图如下: 一.主要的功能: 1.长按显示进度条,单击事件,录制完成回调 2.最大时间和最小时间控制 3.进度条宽度,颜色设置 二.实 ...
- okhttp使用心得(https验证不通过)(一)
之前项目使用的是okhttp3.4版本的,tls协议支持1.0 1.2 等等 后来换成okhttp3.8.1,发现握手失败 找了好多原因之后 发现吧tls加上1.0后,就可以握手成功了,但是tls1 ...
- ubuntu 14.04 安装redis
root@hett-PowerEdge-T30:~# sudo apt-get install redis-server Reading package lists... DoneBuilding d ...
- CNNs 在图像分割中应用简史: 从R-CNN到Mask R-CNN
作者:嫩芽33出处:http://www.cnblogs.com/nenya33/p/6756024.html 版权:本文版权归作者和博客园共有 转载:欢迎转载,但未经作者同意,必须保留此段声明:必须 ...
- 迅为10.1寸人机界面工业HMI安卓电容屏定制生产供应商
10.1寸人机界面介绍: 配置铁电存储器:非易失性记忆体,掉电后数据不丢失. 连接云端,支持云服务:数据综合管理,更有效率. 静电防护技术:高强度抗干扰,防静电,防电磁干扰. 提供所有接口的调用源码, ...
- ssh的server安装和安装指定版本的软件的方法
ssh程序分为有客户端程序openssh-client和服务端程序openssh-server.如果需要ssh登陆到别的电脑,需要安装openssh-client,该程序ubuntu是默认安装的.而如 ...