求1~n与x互质的数的个数(6个题、容斥原理)
2015-10-24 22:14
435 查看
HDU 4135、POJ 2773、HDU 1695、HDU 2841、ZOJ 2836、HDU 1796
HDU 4135 Co-prime
题意: 求[l,r]与x互质的数的个数
分析: 裸题
代码:
POJ 2773 Happy 2006
题意: 求第k个[l,r]与x互质的数
分析: 裸题上二分一下
代码:
HDU 1695 GCD
题意: 求[1,l]和[1,r]两个区间元素对gcd(x,y)=k的个数
分析: 除k后变成gcd(x,y)=1,然后枚举x,保证x<y就好了,特判k=0
代码:
HDU 2841 Visible Trees
题意: 站在(0,0),看(1,1)到(n,m)这个网格的格点,能看到多格点
分析: 易知只有gcd(x,y)=1才能被看到,枚举小的那个坐标,没有然后了
代码:
ZOJ 2836 Number Puzzle
题意: 求[1,m]中能被列表中至少一个数整除 的数的个数
分析: 同理,不过乘的时候要求lcm,因为可能不互质
代码:
HDU 1796 How many integers can you find
题意: 跟上一个题题意一样
分析: [1,n)右边是开区间,−−n,然后列表数字≥0,先去0,然后就一样了
代码:
HDU 4135 Co-prime
题意: 求[l,r]与x互质的数的个数
分析: 裸题
代码:
// // Created by TaoSama on 2015-10-24 // Copyright (c) 2015 TaoSama. All rights reserved. // //#pragma comment(linker, "/STACK:1024000000,1024000000") #include <algorithm> #include <cctype> #include <cmath> #include <cstdio> #include <cstdlib> #include <cstring> #include <iomanip> #include <iostream> #include <map> #include <queue> #include <string> #include <set> #include <vector> using namespace std; #define pr(x) cout << #x << " = " << x << " " #define prln(x) cout << #x << " = " << x << endl const int N = 1e5 + 10, INF = 0x3f3f3f3f, MOD = 1e9 + 7; typedef long long LL; vector<int> factor; void fact(int x) { factor.clear(); for(int i = 2; i * i <= x; ++i) { if(x % i == 0) { factor.push_back(i); while(x % i == 0) x /= i; } if(x == 1) break; } if(x > 1) factor.push_back(x); } LL calc(LL x) { LL ret = 0; //not co-prime int sz = factor.size(); for(int s = 1; s < 1 << sz; ++s) { int cnt = 0, mul = 1; for(int i = 0; i < sz; ++i) if(s >> i & 1) ++cnt, mul *= factor[i]; if(cnt & 1) ret += x / mul; else ret -= x / mul; } return x - ret; } int main() { #ifdef LOCAL freopen("C:\\Users\\TaoSama\\Desktop\\in.txt", "r", stdin); // freopen("C:\\Users\\TaoSama\\Desktop\\out.txt","w",stdout); #endif ios_base::sync_with_stdio(0); int t; scanf("%d", &t); int kase = 0; while(t--) { LL l, r, k; scanf("%I64d%I64d%I64d", &l, &r, &k); fact(k); printf("Case #%d: %I64d\n", ++kase, calc(r) - calc(l - 1)); } return 0; }
POJ 2773 Happy 2006
题意: 求第k个[l,r]与x互质的数
分析: 裸题上二分一下
代码:
// // Created by TaoSama on 2015-10-24 // Copyright (c) 2015 TaoSama. All rights reserved. // //#pragma comment(linker, "/STACK:1024000000,1024000000") #include <algorithm> #include <cctype> #include <cmath> #include <cstdio> #include <cstdlib> #include <cstring> #include <iomanip> #include <iostream> #include <map> #include <queue> #include <string> #include <set> #include <vector> using namespace std; #define pr(x) cout << #x << " = " << x << " " #define prln(x) cout << #x << " = " << x << endl const int N = 1e5 + 10, INF = 0x3f3f3f3f, MOD = 1e9 + 7; int n, k; typedef long long LL; vector<int> factor; void fact(int x) { factor.clear(); for(int i = 2; i * i <= x; ++i) { if(x % i == 0) { factor.push_back(i); while(x % i == 0) x /= i; } if(x == 1) break; } if(x > 1) factor.push_back(x); } LL calc(LL x) { LL ret = 0; int sz = factor.size(); for(int s = 1; s < 1 << sz; ++s) { int cnt = 0, mul = 1; for(int i = 0; i < sz; ++i) if(s >> i & 1) ++cnt, mul *= factor[i]; if(cnt & 1) ret += x / mul; else ret -= x / mul; } return x - ret; } int main() { #ifdef LOCAL freopen("C:\\Users\\TaoSama\\Desktop\\in.txt", "r", stdin); // freopen("C:\\Users\\TaoSama\\Desktop\\out.txt","w",stdout); #endif ios_base::sync_with_stdio(0); while(scanf("%d%d", &n, &k) == 2) { fact(n); LL l = 1, r = 1e10; while(l <= r) { LL m = l + r >> 1; if(calc(m) < k) l = m + 1; else r = m - 1; } printf("%I64d\n", l); } return 0; }
HDU 1695 GCD
题意: 求[1,l]和[1,r]两个区间元素对gcd(x,y)=k的个数
分析: 除k后变成gcd(x,y)=1,然后枚举x,保证x<y就好了,特判k=0
代码:
// // Created by TaoSama on 2015-10-24 // Copyright (c) 2015 TaoSama. All rights reserved. // //#pragma comment(linker, "/STACK:1024000000,1024000000") #include <algorithm> #include <cctype> #include <cmath> #include <cstdio> #include <cstdlib> #include <cstring> #include <iomanip> #include <iostream> #include <map> #include <queue> #include <string> #include <set> #include <vector> using namespace std; #define pr(x) cout << #x << " = " << x << " " #define prln(x) cout << #x << " = " << x << endl const int N = 1e5 + 10, INF = 0x3f3f3f3f, MOD = 1e9 + 7; vector<int> factor ; void gao() { bool vis = {}; for(int i = 2; i < N; ++i) { if(vis[i]) continue; for(int j = i; j < N; j += i) { vis[j] = true; factor[j].push_back(i); } } } typedef long long LL; int calc(int k, int x) { int ret = 0; int sz = factor[k].size(); for(int s = 1; s < 1 << sz; ++s) { int cnt = 0, mul = 1; for(int i = 0; i < sz; ++i) { if(s >> i & 1) ++cnt, mul *= factor[k][i]; } if(cnt & 1) ret += x / mul; else ret -= x / mul; } return x - ret; } int main() { #ifdef LOCAL freopen("C:\\Users\\TaoSama\\Desktop\\in.txt", "r", stdin); // freopen("C:\\Users\\TaoSama\\Desktop\\out.txt","w",stdout); #endif ios_base::sync_with_stdio(0); int t; scanf("%d", &t); int kase = 0; gao(); while(t--) { int l, r, k; scanf("%d%d%d%d%d", &l, &l, &r, &r, &k); if(k == 0) {printf("Case %d: 0\n", ++kase); continue;} l /= k, r /= k; if(l > r) swap(l, r); LL ans = 0; for(int i = 1; i <= l; ++i) ans += calc(i, r) - calc(i, i - 1); printf("Case %d: %I64d\n", ++kase, ans); } return 0; }
HDU 2841 Visible Trees
题意: 站在(0,0),看(1,1)到(n,m)这个网格的格点,能看到多格点
分析: 易知只有gcd(x,y)=1才能被看到,枚举小的那个坐标,没有然后了
代码:
// // Created by TaoSama on 2015-10-24 // Copyright (c) 2015 TaoSama. All rights reserved. // //#pragma comment(linker, "/STACK:1024000000,1024000000") #include <algorithm> #include <cctype> #include <cmath> #include <cstdio> #include <cstdlib> #include <cstring> #include <iomanip> #include <iostream> #include <map> #include <queue> #include <string> #include <set> #include <vector> using namespace std; #define pr(x) cout << #x << " = " << x << " " #define prln(x) cout << #x << " = " << x << endl const int N = 1e5 + 10, INF = 0x3f3f3f3f, MOD = 1e9 + 7; vector<int> factor ; void gao() { bool vis = {}; for(int i = 2; i < N; ++i) { if(vis[i]) continue; for(int j = i; j < N; j += i) { vis[j] = true; factor[j].push_back(i); } } } int calc(int k, int x) { int ret = 0; int sz = factor[k].size(); for(int s = 1; s < 1 << sz; ++s) { int cnt = 0, mul = 1; for(int i = 0; i < sz; ++i) if(s >> i & 1) ++cnt, mul *= factor[k][i]; if(cnt & 1) ret += x / mul; else ret -= x / mul; } return x - ret; } int main() { #ifdef LOCAL freopen("C:\\Users\\TaoSama\\Desktop\\in.txt", "r", stdin); // freopen("C:\\Users\\TaoSama\\Desktop\\out.txt","w",stdout); #endif ios_base::sync_with_stdio(0); int t; scanf("%d", &t); gao(); while(t--) { int n, m; scanf("%d%d", &n, &m); if(n > m) swap(n, m); long long ans = 0; for(int i = 1; i <= n; ++i) ans += calc(i, m); printf("%I64d\n", ans); } return 0; }
ZOJ 2836 Number Puzzle
题意: 求[1,m]中能被列表中至少一个数整除 的数的个数
分析: 同理,不过乘的时候要求lcm,因为可能不互质
代码:
// // Created by TaoSama on 2015-10-24 // Copyright (c) 2015 TaoSama. All rights reserved. // //#pragma comment(linker, "/STACK:1024000000,1024000000") #include <algorithm> #include <cctype> #include <cmath> #include <cstdio> #include <cstdlib> #include <cstring> #include <iomanip> #include <iostream> #include <map> #include <queue> #include <string> #include <set> #include <vector> using namespace std; #define pr(x) cout << #x << " = " << x << " " #define prln(x) cout << #x << " = " << x << endl const int N = 1e5 + 10, INF = 0x3f3f3f3f, MOD = 1e9 + 7; int n, m, a[15]; typedef long long LL; LL calc() { LL ret = 0; for(int s = 1; s < 1 << n; ++s) { int cnt = 0, mul = 1; for(int i = 0; i < n; ++i) if(s >> i & 1) ++cnt, mul = mul / __gcd(mul, a[i]) * a[i]; if(cnt & 1) ret += m / mul; else ret -= m / mul; } return ret; } int main() { #ifdef LOCAL freopen("C:\\Users\\TaoSama\\Desktop\\in.txt", "r", stdin); // freopen("C:\\Users\\TaoSama\\Desktop\\out.txt","w",stdout); #endif ios_base::sync_with_stdio(0); while(scanf("%d%d", &n, &m) == 2) { for(int i = 0; i < n; ++i) scanf("%d", a + i); printf("%lld\n", calc()); } return 0; }
HDU 1796 How many integers can you find
题意: 跟上一个题题意一样
分析: [1,n)右边是开区间,−−n,然后列表数字≥0,先去0,然后就一样了
代码:
// // Created by TaoSama on 2015-10-24 // Copyright (c) 2015 TaoSama. All rights reserved. // //#pragma comment(linker, "/STACK:1024000000,1024000000") #include <algorithm> #include <cctype> #include <cmath> #include <cstdio> #include <cstdlib> #include <cstring> #include <iomanip> #include <iostream> #include <map> #include <queue> #include <string> #include <set> #include <vector> using namespace std; #define pr(x) cout << #x << " = " << x << " " #define prln(x) cout << #x << " = " << x << endl const int N = 1e5 + 10, INF = 0x3f3f3f3f, MOD = 1e9 + 7; int n, m, a[15]; typedef long long LL; LL calc() { LL ret = 0; vector<int> factor; for(int i = 0; i < n; ++i) if(a[i]) factor.push_back(a[i]); n = factor.size(); for(int s = 1; s < 1 << n; ++s) { int cnt = 0, mul = 1; for(int i = 0; i < n; ++i) if(s >> i & 1) ++cnt, mul = mul / __gcd(mul, a[i]) * a[i]; if(cnt & 1) ret += m / mul; else ret -= m / mul; } return ret; } int main() { #ifdef LOCAL freopen("C:\\Users\\TaoSama\\Desktop\\in.txt", "r", stdin); // freopen("C:\\Users\\TaoSama\\Desktop\\out.txt","w",stdout); #endif ios_base::sync_with_stdio(0); while(scanf("%d%d", &m, &n) == 2) { --m; for(int i = 0; i < n; ++i) scanf("%d", a + i); printf("%I64d\n", calc()); } return 0; }
相关文章推荐
- Codeforces Round #198 (Div. 1)
- 4495: Least Prime factor 找到最小质因子P的第N小正整数
- hdu5072 Coprime 2014鞍山现场赛C题 容斥原理+单色三角
- 二维树状数组
- HDU 1695 GCD
- ZOJ 3547 《The Boss on Mars》(容斥定理)
- USACO 2.3.2 Cow Pedigrees
- USACO 2.3.2 Cow Pedigrees
- hdu1695 综合数论 欧拉函数 分解质因子 容斥原理 打印素数表 各种模板
- 1284 2 3 5 7的倍数
- hdu1695 GCD(容斥原理+欧拉函数)
- hdu1796(容斥原理)
- HDU 4135 Co-prime(容斥原理求互质数)
- hdu1796--How many integers can you find--容斥原理
- HDU 4135&HDU 4407--容斥原理--质因子分解
- HDU 5468 Puzzled Elena (2015年上海赛区网络赛A题)
- HDU 1796 容斥原理
- HDU 4407
- ZOJ 3233 Lucky Number(容斥原理)
- hdu 5212(容斥原理)