hdu 4407 SUM(容斥原理)
2015-09-25 14:59
357 查看
题意:
有一个元素为 1~n 的数列AnA_n,有2种操作(最多1000次):1. 求某段区间 [a,b][a,b] 中与 pp 互质的数的和。
2. 将数列中某个位置元素的值改变。
解析:
刚刚开始的时候想成线段树了,看了题解才明白是用容斥原理来做。对于操作1,解的性质满足区间减法,则我们只需要考虑如何求 [1,n][1,n] 中与 pp 互质的数的和即可。
由于与 p 互质的数的和不太好求,于是可以通过先求出与 p 不互质的数的和。
若一个数 x 若与 p 不互质,当且仅当两者素因子的集合有交集。
根据这个定理,可以先预处理出每个数的质因子,然后利用利用容斥原理求出,到当前终止位置,有多少数字和 pp 不互质。
又由于满足区间减法,所以可以求出有区间内有多少数字和 pp 不互质。那么区间内的和减去区间内和 pp 不互质的数的和就是最终答案。
对于操作2,修改用map记录,每次扫一遍即可,如果原数和cc互质就减掉,修改完的数和cc互质就加上去,总复杂度O(m2∗log(n))O(m^2*log(n))
注意:
n最大为400000,中间过程有n*(n+1),如果用intint会超出范围,所以要用longlonglong long,不然会WA。mymy codecode
[code]#include <cstdio> #include <cstring> #include <algorithm> #include <vector> #include <map> #define pb push_back using namespace std; typedef long long ll; const int N = (int)4e5 + 5; map<int, int> mp; map<int, int>::iterator it; vector<int> prime ; int n, m; int gcd(int a, int b) { if(b == 0) return a; else return gcd(b, a%b); } void getFactor() { for(int i = 2; i < N; i++) { if(prime[i].size() > 0) continue; for(int j = i; j < N; j += i) { prime[j].pb(i); } } } ll cal(int r, int num) { int size = prime[num].size(); ll ret = 0; for(int i = 1; i < (1<<size); i++) { int cnt = 0; ll d = 1; for(int j = 0; j < prime[num].size(); j++) { if((i >> j) & 1) { d *= prime[num][j]; cnt++; } } ll n = r / d; if(cnt & 1) ret += n * (n + 1) / 2 * d; else ret -= n * (n + 1) / 2 * d; } return ret; } ll query(int ql, int qr, int val) { ll n = (qr - ql + 1); ll sum = n * ql + n * (n - 1) / 2; sum -= (cal(qr, val) - cal(ql - 1, val)); for(it = mp.begin(); it != mp.end(); it++) { if(ql <= it->first && it->first <= qr) { if(gcd(val, it->second) == 1) sum += it->second; if(gcd(val, it->first) == 1) sum -= it->first; } } return sum; } int main() { getFactor(); int op, x, y, val; int T; scanf("%d", &T); while(T--) { mp.clear(); scanf("%d%d", &n, &m); while(m--) { scanf("%d", &op); if(op == 1) { scanf("%d%d%d", &x, &y, &val); ll ans = query(x, y, val); printf("%lld\n", ans); }else { scanf("%d%d", &x, &val); mp[x] = val; } } } return 0; }
相关文章推荐
- UML Section Four 行为图
- iMac mac os x鼠标双击打不开文件和文件夹, 能打开网页
- 简单记录python存取中文字符的小问题
- [LeetCode 156] Binary Tree Upside Down
- Chrome浏览器扩展开发系列之十一:NPAPI插件的使用
- 在CentOS下面编译WizNote Qt Project
- 如何在 Linux 中整理磁盘碎片
- 如何在 Linux 中整理磁盘碎片
- 十个PHP高级应用技巧果断收藏
- Nginx作为web服务器的安装配置
- html5 ajax Java接口 上传图片
- GCD下载图片
- 流式编程的的几个实例
- C++ 嵌套类使用(三)
- monkeyrunner 自动化测试 图片对比的实现
- 数据库的知识
- [计划任务 - Linux]三分钟学会cron
- Java基础知识强化86:BigInteger类之BigInteger概述和构造方法
- 遥感数据下载地址
- Several ports (8005, 8080, 8009) required by Tomcat v7.0 Server at localhost are解决方法