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]表 ...
随机推荐
- 在ASP.NET中,后台代码向页面写HTML代码
Literal lt = new Literal();lt.Text = "<a href=\"http://www.czbin.cn\">czbin的博客& ...
- React 实践记录 01 组件开发入门
Introduction 本文组成: Ryan Clark文章Getting started with React的翻译. 博主的实践心得. React由Facebook的程序员创建,是一个非常强大的 ...
- 爬虫requests库的基本用法
需要注意的几个点: 1.后面的s是一个虚拟目录 2.url后面不用加问号,发起请求的时候会自动帮你加上问号 get_url = 'http://www.baidu.com/s' 3. url的特性:u ...
- 除虫记——有关WindowsAPI文件查找函数的一次压力测试
作者:朱金灿 来源:http://blog.csdn.net/clever101 这里说的除虫是指排除bug的意思.今天排除了一个有意思的bug,其中的场景大致是这样的:现在你要统计一个文件夹下非隐藏 ...
- Spark-水库抽样-根据抽样率确定每个分区的样本大小
/* * 输入:采样率,待采样的RDD * 输出:每个分区的样本大小(记录数) * 由采样率确定,每个分区的样本大小 */ def findNumPerPartition[T: ClassTag, U ...
- SVN中trunk,branches,tags用法详解【转】
Subversion有一个很标准的目录结构,是这样的.比如项目是proj,svn地址为svn://proj/,那么标准的svn布局是 svn://proj/|+-trunk+-branches+-ta ...
- Mysql的Root密码忘记,查看或修改的解决方法
Mysql的Root密码忘记,查看或修改的解决方法:1.首先启动命令行2.在命令行运行:taskkill /f /im mysqld-nt.exe3.继续在命令行运行:mysqld-nt --skip ...
- docker配置国内镜像
1. 配置 root@ros-OptiPlex-3050:~# cat /etc/docker/daemon.json { "graph": "/mnt/docke ...
- 关于自动化测试环境的集成(Jenkins+RobotFramework+TestLink+SVN)
本人主要从事网络安全产品的测试,由于一些产品功能在后期稳定后每个版本的迭代仍需要投入大量的时间和精力去测试,所以近期计划逐步的去了解自动化测试的一些内容来节省和解放一些资源.由于自己并没有什么编码基础 ...
- python打飞机pro版
# -*- coding: utf-8 -*- import pygame from sys import exit import random pygame.init() screen = pyga ...