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]表 ...
随机推荐
- [已读]了不起的Node.js
2015/1/22 昨天下班前看完了这本,也不算看完,redis与mysql部分没有去翻,觉得暂时用不上. 觉得第一部分的内容还不错. 第二部分主要讲fs,tcp和http这三个模块. 第三个部分是例 ...
- 如何正确在IDEA 里maven构建的项目中引入lib的jar包(图文详解)
不多说,直接上干货! 问题详情 以下是我,maven构建出来的最新spark2.2.0-bin-hadoop2.6的项目. 有些依赖包,maven还是无法一次性满足,所以,得手动加入lib的jar包. ...
- gin实现spring boot url拦截器
1.定义中间件 func middle(c *gin.Context) { fmt.Println("我是中间件") c.Next() } 2.对要拦截的路由进行分组并引入中间件 ...
- Java编程基础-数组
一.数组的定义. 1.数组的含义:数组是一组具有相同数据类型的元素的有序集合.数组可以分为一维数组和多维数组.(数组是一个引用类型的容器,从0开始编号存储相同数据类型的数据.) 2.数组的定义语法格式 ...
- 洛谷P2827 蚯蚓(单调队列)
题意 初始时有$n$个蚯蚓,每个长度为$a[i]$ 有$m$个时间,每个时间点找出长度最大的蚯蚓,把它切成两段,分别为$a[i] * p$和$a[i] - a[i] * p$,除这两段外其他的长度都加 ...
- Android 滑动RecyclerView时隐藏部分控件
在使用RecyclerView控件时,上下拖动控件时的时候,需要实时的隐藏与显示部分控件,已到达很好的用户体验. 原理很简单,当RecyclerView拖动至最上层时显示控件,当RecyclerV ...
- Android仿ios底部弹出框效果
准备: public class ActionSheet { public interface OnActionSheetSelected { void onClick(int whichButton ...
- uvm_env——UVM大环境(UVM Environment )
1 What is uvm_env? uvm_env is used to create and connect the uvm_components like driver, monitors , ...
- HTML iframe框架
iframe 作用: 就是在一个网页插入一个小窗口 窗口里面也是一个网页 <a href="http://www.baidu.com" target="da1& ...
- 在hibernate框架中配置显示sql语句
使用Hibernate的框架开发时,可在Hibernate.cfg.xml中加上 <property name="hibernate.show_sql">true< ...