zoukankan      html  css  js  c++  java
  • HDU 4135 Co-prime(容斥原理)

    题目链接

    题目大意

      求区间内与n互质的数的数量。

    解题思路

      对于区间显然用[b,1]-[1,a-1]的结果就行了。反过来想,从原来的数中删去与n不互质的数。将n分解质因数,然后利用容斥原理去掉与n有公因数的数即可。
      假设分解质因数的结果是2,3,5,观察发现结果就是去掉能被2,3,5整除的数,加上能被2和3,2和5,3和5整除的数,加上能被2和3和5整除的数,当去掉的数是一个奇数项时是减号,偶数项时时加号。同时,每新加入一个质因子,就是在前面的结果上都乘上这个质因子(假设第一个数是1)。

    代码

    const int maxn = 1e5+10;
    const int maxm = 2e2+10;
    int p[maxn], u[maxn], q[maxn] = {-1}, __q, k;
    vector<int> tmp;
    ll solve(ll k, ll x) {
        for (int i = 1; (ll)p[i]*p[i]<=x; ++i)
            if (x%p[i]==0) {
                while(x%p[i]==0) x/=p[i];
                tmp.push_back(p[i]);
            }
        if (x>1) tmp.push_back(x);
        ll res = k; __q = 1;
        for (auto num : tmp) {
            int t = __q;
            for (int i = 0; i<t; ++i) q[__q++] = -q[i]*num;
        }
        for (int i = 1; i<__q; ++i) res -= k/q[i];
        tmp.clear();
        return res;
    }
    int main() {
        for (int i = 2; i<maxn; ++i) {
            if (!u[i]) u[i] = p[++p[0]] = i;
            for (int j = 1; i*p[j]<maxn; ++j) {
                u[i*p[j]] = p[j];
                if (i%p[j]==0) break;
            }
        }
        int t; scanf("%d", &t);
        while(t--) {
    		ll a, b, c; scanf("%lld%lld%lld", &a, &b, &c);
            printf("Case #%d: %lld
    ", ++k, solve(b, c)-solve(a-1, c));
        }
        return 0;
    }
    
  • 相关阅读:
    linux之正则表达式
    ssh远程连接centos
    centOS网络配置
    linux软件包的管理
    linux内存、进程管理
    cent_os_7进行磁盘分区
    linux文件压缩、磁盘分区、vi和软硬链接
    linux用户、群操作命令和文件权限修改
    c#控制台程序
    c#简易程序解释1
  • 原文地址:https://www.cnblogs.com/shuitiangong/p/13573219.html
Copyright © 2011-2022 走看看