zoukankan      html  css  js  c++  java
  • hdu5728 PowMod

    hdu5728 PowMod

    给定 (n, m, p) ,令 (k=displaystylesum_{i=1}^mvarphi(i imes n)pmod{10^9+7})

    (k^{k^{k^{cdots^{k}}}}pmod{p})

    (T) 组询问, (n) 无平方因子

    (Tleq100, n, m, pleq10^7)

    数论,计数


    (f(n, m)=displaystylesum_{i=1}^mvarphi(i imes n)) 。假设 (p)(n) 的一个质因子,若 ((i, n)=1) ,则 (varphi(i imes n)=varphi(i) imesvarphi(n)) ,否则若 (p | i) ,可以将 (i) 看作 (k imes p) ,否则 (p ot |;i) ,于是分类讨论

    [egin{aligned}f(n, m)&=displaystylesum_{i=1}^m{[p | i](varphi(p) imesvarphi(i imesfrac{n}{p}))}+sum_{i=1}^{frac{m}{p}}varphi(i imes n imes p)\&=varphi(p) imessum_{i=1}^m{[p ot|;i]varphi(i imesfrac{n}{p})+p imessum_{i=1}^{frac{m}{p}}varphi(i imes n)}\&=varphi(p) imessum_{i=1}^m{[p ot|;i]varphi(i imesfrac{n}{p})+(varphi(p)+1) imessum_{i=1}^{frac{m}{p}}varphi(i imes n)}\&=varphi(p) imessum_{i=1}^m{[p ot|;i]varphi(i imesfrac{n}{p})}+varphi(p) imessum_{i=1}^{frac{m}{p}}varphi(i imes n)+sum_{i=1}^{frac{m}{p}}varphi(i imes n)end{aligned} ]

    但前两项是可以合并的,第二项恰好将第一项补全了,于是

    [f(n, m)=varphi(p) imessum_{i=1}^mvarphi(i imesfrac{n}{p})+sum_{i=1}^{frac{m}{p}}varphi(i imes n) ]

    所以 $$f(n, m)=varphi(p) imes f(frac{n}{p}, m)+f(n, frac{m}{p})$$

    递归时枚举一个质因子就够了

    而求 (k^{k^{k^{cdots^{k}}}}pmod{p}) 直接用欧拉定理就可以了

    时间复杂度 (O() 能过 ())

    #include <bits/stdc++.h>
    using namespace std;
    
    const int maxn = 1e7 + 10, P = 1e9 + 7;
    int tot, p[maxn], phi[maxn], sum[maxn];
    
    inline int inc(int x, int y) {
      return x + y < P ? x + y : x + y - P;
    }
    
    inline int qp(int a, int k, int P) {
      int res = 1;
      for (; k; k >>= 1, a = 1ll * a * a % P) {
        if (k & 1) res = 1ll * res * a % P;
      }
      return res;
    }
    
    void sieve() {
      int N = 10000000;
      for (int i = 2; i <= N; i++) {
        if (!p[i]) p[++tot] = i, phi[i] = i - 1;
        for (int j = 1; j <= tot && i * p[j] <= N; j++) {
          p[i * p[j]] = 1;
          if (i % p[j] == 0) {
            phi[i * p[j]] = phi[i] * p[j]; break;
          }
          phi[i * p[j]] = phi[i] * (p[j] - 1);
        }
      }
      phi[1] = 1;
      for (int i = 1; i <= N; i++) {
        sum[i] = inc(sum[i - 1], phi[i]);
      }
    }
    
    int dfs(int a, int P) {
      int t = phi[P];
      return t == 1 ? 0 : qp(a, dfs(a, t) % t + t, P);
    }
    
    int calc(int n, int m) {
      if (!m) return 0;
      if (n == 1) return sum[m];
      int tmp = sqrt(n);
      for (int i = 2; i <= tmp; i++) {
        if (n % i == 0) {
          return (calc(n, m / i) + 1ll * phi[i] * calc(n / i, m)) % P;
        }
      }
      return (calc(n, m / n) + 1ll * phi[n] * sum[m]) % P;
    }
    
    int main() {
      sieve();
      int n, m, p;
      while (~scanf("%d %d %d", &n, &m, &p)) {
        printf("%d
    ", dfs(calc(n, m), p));
      }
      return 0;
    }
    
  • 相关阅读:
    gdb段错误
    gdb断点
    init.d详解
    asp.net中的服务器端控件 textbox 设为只读属性后无法获取 javascript给其赋的值
    关于“金点子”征集通知
    Notepad++ SQL Assistant
    IoC Container Benchmark Unity, Windsor, StructureMap and Spring.NET
    如何判断个人电脑是多少位(32位?还是64位系统)
    批量执行SQL文件
    SQL Server 2005 dev 开发板 版本说明
  • 原文地址:https://www.cnblogs.com/Juanzhang/p/11044555.html
Copyright © 2011-2022 走看看