hdu5728 PowMod

Posted juanzhang

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了hdu5728 PowMod相关的知识,希望对你有一定的参考价值。

hdu5728 PowMod

给定 \(n,\ m,\ p\) ,令 \(k=\displaystyle\sum_i=1^m\varphi(i\times n)\pmod10^9+7\)

\(k^k^k^\cdots^k\pmodp\)

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

\(T\leq100,\ n,\ m,\ p\leq10^7\)

数论,计数


\(f(n,\ m)=\displaystyle\sum_i=1^m\varphi(i\times n)\) 。假设 \(p\)\(n\) 的一个质因子,若 \((i,\ n)=1\) ,则 \(\varphi(i\times n)=\varphi(i)\times\varphi(n)\) ,否则若 \(p\ |\ i\) ,可以将 \(i\) 看作 \(k\times p\) ,否则 \(p\not |\;i\) ,于是分类讨论

\[\beginalignedf(n,\ m)&=\displaystyle\sum_i=1^m[p\ |\ i](\varphi(p)\times\varphi(i\times\fracnp))+\sum_i=1^\fracmp\varphi(i\times n\times p)\\&=\varphi(p)\times\sum_i=1^m[p\not|\;i]\varphi(i\times\fracnp)+p\times\sum_i=1^\fracmp\varphi(i\times n)\\&=\varphi(p)\times\sum_i=1^m[p\not|\;i]\varphi(i\times\fracnp)+(\varphi(p)+1)\times\sum_i=1^\fracmp\varphi(i\times n)\\&=\varphi(p)\times\sum_i=1^m[p\not|\;i]\varphi(i\times\fracnp)+\varphi(p)\times\sum_i=1^\fracmp\varphi(i\times n)+\sum_i=1^\fracmp\varphi(i\times n)\endaligned\]

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

\[f(n,\ m)=\varphi(p)\times\sum_i=1^m\varphi(i\times\fracnp)+\sum_i=1^\fracmp\varphi(i\times n)\]

所以 \[f(n,\ m)=\varphi(p)\times f(\fracnp,\ m)+f(n,\ \fracmp)\]

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

而求 \(k^k^k^\cdots^k\pmodp\) 直接用欧拉定理就可以了

时间复杂度 \(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\n", dfs(calc(n, m), p));
  
  return 0;

以上是关于hdu5728 PowMod的主要内容,如果未能解决你的问题,请参考以下文章

am5728 中断的使用

am5728 中断的使用

am5728 中断的使用

基于AM5728的PROFIBUS 通信测试

安装openssh 到 am5728 板子上

am5728评估板_支持双核Cortex-A15_主频最高1.5GHz/核