hdu4135 co-prime(容斥原理)

来源:互联网 发布:大数据徐子沛百度云 编辑:程序博客网 时间:2024/06/05 17:56


题意:给定a、b、c,求a到b区间内与c互质的数。

思路:求a到b之间的与c互素的数,等价于求1到b之间与c互素的数减去1到a之间与c互素的数。求1~n中与n互质的数的个数都是用欧拉函数, 但如果n比较大或者是求1~m中与n互质的数的个数等等问题, 要想时间效率高的话还是先对n分解质因数然后用容斥原理,这里可以用状态压缩简化,每一位1代表乘积项里有这位对应的质因子,反之则没有。

#include<cstdio>  #include<cstring>  #include<cmath>  #include<cstdlib>  #include<iostream>  #include<algorithm>  #include<vector>  #include<map>  #include<queue>  #include<stack> #include<string>#include<map> #include<set>#define eps 1e-6 #define LL long long  using namespace std;  //const int maxn = 100 + 5;//const int INF = 0x3f3f3f3f;//freopen("input.txt", "r", stdin);LL n, A, B;int kase;vector<int> vt;void init() {vt.clear();    for(LL i=2;i*i<=n;i++)             if(n%i==0){            vt.push_back(i);            while(n%i==0)                n/=i;        }    if(n>1)        vt.push_back(n);}LL solve(LL x) {LL ans = x;for(int i = 1; i < (1 << (vt.size())); i++) {LL divisor = 1;int cnt = 0;for(int j = 0; j < vt.size(); j++) {if((1<<j)&i) {divisor *= vt[j];cnt++;}}if(cnt%2) ans -= x/divisor;else ans += x/divisor;}return ans;}int main() {int t; cin >> t;while(t--) {cin >> A >> B >> n;init();cout << "Case #" << ++kase << ": " << solve(B) - solve(A-1)<< endl;}return 0;}

0 0