HDU 2841 Visible Trees(莫比乌斯反演)
2015-09-08 15:29
447 查看
题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=2841
题意:给n*m的矩阵(从(1,1)开始编号)格子,每个格子有一棵树,人站在(0,0)的位置,求可以看到多少棵树。同一直线上的树只能看到最靠近人的那颗。
思路:可以将题目转化为求gcd(x, y) = 1,(1 <= x <= n, 1 <= y <= m)的对数。直接套用莫比乌斯反演即可。
code:
题意:给n*m的矩阵(从(1,1)开始编号)格子,每个格子有一棵树,人站在(0,0)的位置,求可以看到多少棵树。同一直线上的树只能看到最靠近人的那颗。
思路:可以将题目转化为求gcd(x, y) = 1,(1 <= x <= n, 1 <= y <= m)的对数。直接套用莫比乌斯反演即可。
code:
#include <cstdio> #include <cstring> #include <algorithm> using namespace std; typedef long long LL; const int MAXN = 1000005; bool check[MAXN]; int primes[MAXN]; int mu[MAXN]; void moblus() { memset(check, false, sizeof(check)); mu[1] = 1; int cnt = 0; for (int i = 2; i < MAXN; ++i) { if (!check[i]) { primes[cnt++] = i; mu[i] = -1; } for (int j = 0; j < cnt; ++j) { if (i * primes[j] > MAXN) break; check[i * primes[j]] = true; if (i % primes[j] == 0) { mu[i * primes[j]] = 0; break; } else { mu[i * primes[j]] = -mu[i]; } } } } int main() { moblus(); int nCase; scanf("%d", &nCase); while (nCase--) { int n, m; scanf("%d %d", &n, &m); if (n < m) swap(n, m); LL ans = 0; for (int i = 1; i <= m; ++i) { ans += (LL)mu[i] * (n / i) * (m / i); } printf("%lld\n", ans); } return 0; }
相关文章推荐
- 【LeetCode】112. Path Sum
- org.apache.commons.discovery.tools.DiscoverSingleton 报错
- Centos7 安装kilo-1 总览
- 基于key-value的存储系统Redis
- Postman 编辑和发送Cookie
- 苏联的存与亡都是我们的营养
- 关于spring mvc web工程上传下载中文文件出现乱码的问题
- 推荐系统简介——基于协同过滤的推荐
- "abc_shareactionprovider_share_with" is not translated in "he" (Hebrew), "zh" (Chinese)
- JavaScript 设计模式之外观模式
- char*,const char*和string 三者转换
- sar查看各种io
- 多终端WEB页面字体处理方法总结
- 阿里云监控用户手册
- Mysql innodb_flush_log_trx_commit 简单调优
- 该不该写技术博客
- 掌握 Markdown,例子
- mapreduce的二次排序 SecondarySort
- CentOS6.5升级为CentOS7.0
- iOS测试-GHUnit配置