hdu5728 PowMod

hdu5728 PowMod

给定 \(n,\ m,\ p\) ,令 \(k=\displaystyle\sum_{i=1}^m\varphi(i\times n)\pmod{10^9+7}\)

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

共 \(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\) ,于是分类讨论

\[\begin{aligned}f(n,\ m)&=\displaystyle\sum_{i=1}^m{[p\ |\ i](\varphi(p)\times\varphi(i\times\frac{n}{p}))}+\sum_{i=1}^{\frac{m}{p}}\varphi(i\times n\times p)\\&=\varphi(p)\times\sum_{i=1}^m{[p\not|\;i]\varphi(i\times\frac{n}{p})+p\times\sum_{i=1}^{\frac{m}{p}}\varphi(i\times n)}\\&=\varphi(p)\times\sum_{i=1}^m{[p\not|\;i]\varphi(i\times\frac{n}{p})+(\varphi(p)+1)\times\sum_{i=1}^{\frac{m}{p}}\varphi(i\times n)}\\&=\varphi(p)\times\sum_{i=1}^m{[p\not|\;i]\varphi(i\times\frac{n}{p})}+\varphi(p)\times\sum_{i=1}^{\frac{m}{p}}\varphi(i\times n)+\sum_{i=1}^{\frac{m}{p}}\varphi(i\times n)\end{aligned}\]

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

\[f(n,\ m)=\varphi(p)\times\sum_{i=1}^m\varphi(i\times\frac{n}{p})+\sum_{i=1}^{\frac{m}{p}}\varphi(i\times n)\]

所以 \[f(n,\ m)=\varphi(p)\times 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\n", dfs(calc(n, m), p));
  }
  return 0;
}

原文地址:https://www.cnblogs.com/Juanzhang/p/11044555.html

时间: 2024-10-12 02:51:37

hdu5728 PowMod的相关文章

hdu-5728 PowMod(数论)

题目链接: PowMod Time Limit: 3000/1500 MS (Java/Others)     Memory Limit: 262144/262144 K (Java/Others) Problem Description Declare:k=∑mi=1φ(i∗n) mod 1000000007 n is a square-free number. φ is the Euler's totient function. find:ans=kkkk...k mod p There a

HDU 5728 - PowMod

题意:    定义: k = ∑(i=1,m) φ(i∗n) mod 1000000007 给出: n,m,p ,且 n 无平方因子 求: ans= k^(k^(k...k)) mod p  (k有无限个)    分析: 欧拉函数 + 指数循环节        第一部分 求出 k.        定理: 1.欧拉函数是非完全积性函数: φ(m*n) = φ(n)*φ(m) , 当且仅当GCD(n,m) = 1.        应用:            ∑(i=1,m)φ(i*n) = φ(p

hdu5728

详细题解: http://blog.csdn.net/wust_zzwh/article/details/51966450 --化简公式的能力还不够啊-- 1 #include<bits/stdc++.h> 2 3 using namespace std; 4 typedef long long ll; 5 const int mo=1e9+7; 6 const int mx=1e7; 7 bool v[mx+5]; 8 int pr[mx+5],phi[mx+5],s[mx+5],a[100

HDU 5278 PowMod 数论公式推导

题意:中文题自己看吧 分析:这题分两步 第一步:利用已知公式求出k: 第二步:求出k然后使用欧拉降幂公式即可,欧拉降幂公式不需要互质(第二步就是BZOJ3884原题了) 求k的话就需要构造了(引入官方题解) 然后就求出k了,我就很奇怪为什么是这个式子,然后就网上搜啊搜 找到了一个推导(看完了以后恍然大悟) 推导链接:http://blog.csdn.net/wust_zzwh/article/details/51966450 高度仰慕数学好的巨巨 吐槽:这个题n是无平方因子,然后就要往欧拉函数是

python实现网页登录时的rsa加密流程

对某些网站的登录包进行抓包时发现,客户端对用户名进行了加密,然后传给服务器进行校验. 使用chrome调试功能断点调试,发现网站用javascript对用户名做了rsa加密. 为了实现网站的自动登录,需要模拟这个加密过程. 网上搜了下关于rsa加密的最简明的解释: rsa加密是非对称加密算法,该算法基于一个十分简单的数论事实:将两个大素数相乘十分容易,但那时想要对其乘积进行因式分解却极其困难,因此可以将乘积公开作为加密密钥,即公钥,而两个大素数组合成私钥.公钥是可发布的供任何人使用,私钥则为自己

20170726测试

终于有水一点的题了: Day1: 第1题 谜题首先请解以下谜题:车下的数字是什么? -----------------------图被吃掉了---------------------------------- 正确的答案是87 .这道题对小龙大犇来说太轻松了,于是他想加强难度来考考你:对于给定的长度N,能否获得刚好长度为N的数列,使数列中的每个数经过翻转恰好是连续的数,如N==3时,数列 11 01 60 是合法的.数字的翻转符合以下规定:1.0.8翻转后是其本身:6和9翻转后互相转变:其他数字

HDU 1075 What Are You Talking About (Trie树)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1075 map可以过...我上的字典树,小bug有点尴尬,题目没有明确给出数据范围也是无奈. 贡献了几次RE 一次WA.尴尬.discuss里面有个说注意前缀的到是给了点tip.总体来说不错 代码: 1 #define _CRT_SECURE_NO_WARNINGS 2 #include <functional> 3 #include <algorithm> 4 #include <

POJ2100 Graveyard Design(尺取法)

POJ2100 Graveyard Design 题目大意:给定一个数n,求出一段连续的正整数的平方和等于n的方案数,并输出这些方案,注意输出格式: 循环判断条件可以适当剪支,提高效率,(1^2+2^2+..n^2)=n*(n+1)*(2n+1)/6; 尺取时一定要注意循环终止条件的判断. #include <cstdio> #include <cstdlib> #include <cstring> #include <cmath> #include <

我的模板(持续更新ing)[还很混乱]

1.头文件 短的: 1 #include<bits/stdc++.h> 2 #define cl(a,b) memset(a,b,sizeof(a)) 3 #define debug(a) cerr<<#a<<"=="<<a<<endl 4 using namespace std; 5 typedef long long ll; 6 typedef pair<int,int> pii; 7 8 const int