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]表 ...
随机推荐
- F. Bakkar In The Army 二分
http://codeforces.com/gym/100283/problem/F 思路是二分第几行,二分出来的行是总和 >= n的,那么第k - 1行一定要选,那么再在第k行中二分那一列. ...
- 【Linux】使用Cockpit进行主机管理
Cockpit 进行主机监控 官网文档: https://cockpit-project.org/running.html 版本信息 针对Red Hat [root@master ~]# cat /e ...
- ubuntu 14.04 安装mysql,并配置远程连接和中文乱码
1. 安装MySQL的jar root@computer-PowerEdge-T30:~# sudo apt-get install mysql-server mysql-client在本次安装中,根 ...
- windows8无脑式双系统安装教程(转)
转:http://blog.csdn.net/poem_qianmo/article/details/7334987 首先去微软官网将ISO文件下载下来,分为32bit跟64bit两个版本,因人而异, ...
- 更新Svn客户端后,右键菜单中没有TortoiseSVN
环境: OS: Windows XP sp3 升级后SVNServer: VisualSVN Server 2.7.3 升级后SVNClient: 小乌龟: ...
- PyTorch在NLP任务中使用预训练词向量
在使用pytorch或tensorflow等神经网络框架进行nlp任务的处理时,可以通过对应的Embedding层做词向量的处理,更多的时候,使用预训练好的词向量会带来更优的性能.下面分别介绍使用ge ...
- python基础一 day14 生成器函数进阶
def generator(): print(123) content = yield 1 print('=======',content) print(456) arg = yield 2 '''' ...
- 看paper的网址
http://www.arxiv-sanity.com/ https://scirate.com/ google搜cvpr open access.iccv open access
- urlrewrite地址重写实例
urlrewrite主要实现后天请求中的地址重写,防止被安全漏洞盲注入 http://tuckey.org/urlrewrite/ 下载最新的jar 下面是使用说明: 1.下载urlrewrite,官 ...
- Noip2016 提高组 蚯蚓
刚看到这道题:这题直接用堆+模拟不就可以了(并没有认真算时间复杂度) 于是用priority_queue水到了85分-- (STL大法好) 天真的我还以为是常数问题,于是疯狂卡常--(我是ZZ) 直到 ...