zoukankan      html  css  js  c++  java
  • UVa 11440 Help Tomisu (欧拉函数)

    题目

    题目大意

    给定正整数(N)(M), 统计(2)(N!)之间有多少个整数(x)满足: (x)的所有素因子都大于(M)((2 ≤ N ≤ 10^7), (1 ≤ M ≤ N), (N - M ≤ 10^5))。输出答案除以(100000007)的余数。例如, (N = 100), (M = 10)时的答案为(43274465)

    题解

    因为(M ≤ N), 所以(N!)(M!)的整数倍。所有素因子都大于(M)等价于和(M!)互质。根据最大公约数的性质, 对于(k > M!), (k)(M!)互质当且仅当(k mod M!)(M!)互质。这样就只需要求出不超过(M!)且与(M!)互质的正整数个数, 再乘以(frac{N!}{M!})即可。

    根据欧拉函数的公式:

    [phi(n) = n(1 - frac{1}{p_1})(1 - frac{1}{p_2})cdots(1 - frac{1}{p_k}) ]

    如果(n)不是质数, 那么(n!)((n - 1)!)的质因子集合相同, 因此(phifac(n) = n phifac(n - 1)); 如果(n)是质数, 那么还会多一项((1 - frac{1}{n})), 即(phifac(n) = (n - 1) phifac(n - 1))

    代码

    #include <cstdio>
    #include <cstring>
    const long long kMod(100000007);
    long long phifac[10000010] = {0, 1, 1};
    bool mark[10000010];
    long long n, m;
    long long ans;
    int main(int argc, char const *argv[]) {
      memset(mark, true, sizeof(mark));
      mark[0] = mark[1] = false;
      for (register int i(2); i <= 10000000; ++i) {
        if (mark[i]) {
          for (register int j(2); i * j <= 10000000; ++j) {
            mark[i * j] = false;
          }
        }
      }
      for (register long long i(3); i <= 10000000; ++i) {
        phifac[i] = phifac[i - 1] * (mark[i] ? i - 1 : i) % kMod;
      }
      while (~scanf("%lld %lld", &n, &m) && (n || m)) {
        ans = phifac[m];
        for (register long long i(m + 1); i <= n; ++i) ans = ans * i % kMod;
        printf("%lld
    ", (ans - 1 + kMod) % kMod);
      }
      return 0;
    }
    
  • 相关阅读:
    ROS配置C++14环境
    ubantu查看环境变量
    C++指向函数的指针
    ubantu删除文件(夹)
    ROS环境搭建
    vmware workstation pro 安装ubantu虚拟机
    Win7下删除Ubuntu启动项
    ubantu16.04
    ubantu卸载软件
    github之克隆
  • 原文地址:https://www.cnblogs.com/forth/p/9724751.html
Copyright © 2011-2022 走看看