• [bzoj2186][Sdoi2008]沙拉公主的困惑——数论


    题目大意

    [sum_{i = 1}^{N!} [gcd(i, M!) = 1] ]

    题解

    显然,题目就是求

    [N!(1-frac{1}{p_1})(1-frac{1}{p_2})... ]

    [N!prod(p_i - 1)(prod p_i)^{-1} ]

    预处理一下,都是线性复杂度。
    注意:

    1. N=1的情况
    2. long long

    所以,数论题一定要注意各种特殊情况和longlong

    代码

    #include <bits/stdc++.h>
    #define ll long long
    using namespace std;
    const int maxn = 10000110;
    const int N = 10000010;
    int n, m, t, r;
    int prime[maxn], check[maxn], d[maxn];
    int prd1[maxn], prd2[maxn], fact[maxn];
    int tot = 0;
    
    inline int read() {
      char c = getchar();
      int f = 1, x = 0;
      while (!isdigit(c)) {
        if (c == '-')
          f = -1;
        c = getchar();
      }
      while (isdigit(c))
        x = x * 10 + c - '0', c = getchar();
      return x * f;
    }
    
    inline void get_prime(int n) {
      memset(check, 0, sizeof(check));
      for (int i = 2; i <= n; i++) {
        if (!check[i])
          prime[tot++] = i;
        for (int j = 0; j < tot; j++) {
          if (i * prime[j] > n)
            break;
          check[i * prime[j]] = 1;
          if (i % prime[j] == 0)
            break;
        }
      }
    }
    inline void get_prd(int p) {
      // get prd (p_i - 1) and prd (p_i);
      prd1[0] = 1;
      prd2[0] = 2;
      for (int i = 1; i <= tot; i++) {
        prd1[i] = (((ll)prime[i] - 1) % p * (ll)prd1[i - 1]) % p;
        prd2[i] = (ll)(prime[i] % p * (ll)prd2[i - 1]) % p;
      }
    }
    inline void init() {
    
      for (int i = 0; i < tot; i++) {
        for (int j = prime[i]; j < prime[i + 1]; j++)
          d[j] = i;
      }
      fact[0] = fact[1] = 1;
      for (int i = 2; i <= N; i++)
        fact[i] = (ll)(fact[i - 1] * (ll)i) % r;
    }
    int pow(int a, int b, int p) {
      int x = 1;
      int c = b;
      while (c) {
        if (c & 1)
          x = (ll)((ll)x * a) % p;
        a = (ll)((ll)a * a) % p;
        c >>= 1;
      }
      return x;
    }
    int inv(int a, int p) { return pow(a, p - 2, p); }
    int main() {
      scanf("%lld %lld", &t, &r);
      get_prime(N);
      get_prd(r);
      init();
      while (t--) {
        n = read();
        m = read();
        if (m == 1) {
          printf("%lld
    ", fact[n]);
          continue;
        }
        int ans = ((ll)((ll)fact[n] * prd1[d[m]]) % r * (ll)inv(prd2[d[m]], r)) % r;
        printf("%d
    ", ans);
      }
    }
    
  • 相关阅读:
    linux下使用kermi续
    关于vhdl中integer消耗资源的一些讨论
    linux时间编程
    Linux下C编程文件编程
    C语言I博客作业04
    C语言I博客作业02
    C语言I博客作业02
    第一周作业
    php 面向对象
    php 面向对象封装和继承
  • 原文地址:https://www.cnblogs.com/gengchen/p/6431772.html
Copyright © 2020-2023  润新知