HDU4135 Co-prime 容斥原理
Posted hznumqf
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HDU4135 Co-prime 容斥原理相关的知识,希望对你有一定的参考价值。
第一做容斥原理,开始真的不太好理解
题意:给出a,b<=1e19 n<=1e9 ,问[a,b]中与n互质的个数
考虑[a,b]中与n不互质的个数,对n唯一分解定理,与n不互质的个数即为n/p,但是考虑到会有重复,且若数字个数是奇数则要+,偶数减去,因此借助二进制遍历每一种情况(极其神奇的思想)
代码值得好好思考
#pragma warning(disable:4996) #include<iostream> #include<unordered_map> #include<algorithm> #include<string> #include<cmath> #include<cstring> #include<vector> #include<map> #include<set> #include<queue> #include<deque> #include<stack> #include<sstream> #include <cstdlib> #include<cstdio> #include<random> #define INF 0x3f3f3f3f #define eps 1e-8 #define equals(a,b) (fabs(a-b)<eps) #define MOD 100000007 std::mt19937 rnd(233); //#define rnd() rand()%1000 const int maxn = 1e7+5 ; const double PI = acos(-1.0); typedef long long ll; using namespace std; ll p[maxn]; int cnt; ll n; void init(ll m) { for (int i = 2; i * i <= m; i++) { if (m % i == 0) { p[cnt++] = i; while (m % i == 0) m /= i; } } if (m > 1) p[cnt++] = m; } ll solve(ll x) { ll len = 1ll << cnt; ll ans = 0; for (ll i = 1; i < len; i++) { int f = 0; ll tmp = 1; for (ll j = 0; j < cnt; j++) { if (i & (1ll << j)) { f++; tmp *= p[j]; } } if (f & 1) ans += x / tmp; else ans -= x/ tmp; } return ans; } int main() { int T; ll a, b; scanf("%d", &T); int kase = 1; while (T--) { cnt = 0; scanf("%lld%lld%lld", &a, &b, &n); init(n); printf("Case #%d: %lld ", kase++, (b - a + 1) - (solve(b) - solve(a - 1))); } return 0; }
以上是关于HDU4135 Co-prime 容斥原理的主要内容,如果未能解决你的问题,请参考以下文章