码迷,mamicode.com
首页 > 其他好文 > 详细

HDU 5728 - PowMod

时间:2016-07-24 23:56:18      阅读:257      评论:0      收藏:0      [点我收藏+]

标签:

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) = φ(pi) * ∑(i=1,m)φ(i*n/pi) + ∑(i=1,m/pi)φ(i*n) ; (n无平方因子数) ,可自行推导
    第二部分
          应用指数循环节化无限为有限,具体实现为递归操作
        
         指数循环节: A^x = A^(x % φ(C) + φ(C)) (mod C)  (x >= φ(C))

 

 1 #include <iostream>
 2 #include <cstring>
 3 #include <cstdio>
 4 using namespace std;
 5 const int MOD= 1000000007;
 6 const int MAXN=1e7;
 7 int euler[MAXN+5];
 8 long long sum[MAXN+5];
 9 long long k,n,m,p;
10 void GetEuler()
11 {
12     memset(euler,0,sizeof(euler));
13     euler[1]=1;
14     for(int i = 2;i <= MAXN;i++)
15         if(!euler[i])
16             for(int j = i;j <= MAXN;j += i)
17             {
18                 if(!euler[j]) euler[j]=j;
19                 euler[j] = euler[j] / i * (i-1);
20             }
21     sum[1]=1;
22     for(int i = 2;i <=MAXN; i++)
23         sum[i] = (sum[i-1] + euler[i]) % MOD;
24 }
25 long long Get_K(long long n,long long m)
26 {
27     if(m==0) return 0;
28     if(m==1) return euler[n];
29     if(n==1) return sum[m];
30     if(euler[n]==n-1) return (euler[n]*Get_K(1,m)%MOD + Get_K(n,m/n))%MOD;
31     for(int i=2;i<MAXN;i++)
32         if(n%i==0)
33             return (euler[i] * Get_K(n/i,m)%MOD + Get_K(n,m/i) ) % MOD;
34 }
35 long long PowMod(long long a,long long b, long long mod)
36 {
37     long long r = 1;
38     while(b)
39     {
40         if(b&1) r = (r*a)%mod;
41         a= (a*a)%mod;
42         b>>=1;
43     }
44     return r;
45 }
46 long long Cal(long long k, long long p)
47 {
48     if( p == 2) return k&1;//mod φ(p)
49     return PowMod(k,Cal(k,euler[p])+euler[p],p);//递归的计算ans,递归出口为φ(p)=1
50 }
51 int main()
52 {
53     GetEuler();
54     while(~scanf("%lld%lld%lld",&n,&m,&p))
55     {
56         k = Get_K(n,m);
57         printf("%lld\n",Cal(k,p));
58     }
59 }

 

/*
欧拉函数:
对正整数n,欧拉函数是少于或等于n的数中与n互质的数的数目。   例如euler(8)=4,因为1,3,5,7均和8互质。

通式:
    对于一个正整数N的素数幂分解    N = (P1^q1) * (P2^q2) * ...* (Pn^qn).
        φ(1) = 1.
        φ(N) = N * (1-1/P1) * (1-1/P2) *...* (1-1/Pn).

定理:
    1.欧拉函数是非完全积性函数: φ(m*n) = φ(n)*φ(m) , 当且仅当GCD(n,m) = 1.
    
    2.一个数的所有质因子之和是  euler(n)*n/2.
    
    3.若n是素数p的k次幂,φ(n)=p^k-p^(k-1)=(p-1)p^(k-1),因为除了p的倍数外,其他数都跟n互质.
    
特殊性质: 
    1.当n为奇数时,φ(2n) = φ(n).
    2.对于质数p,φ(p) = p - 1
    3.除了N=2,φ(N)都是偶数.
    
指数循环节:
    A^x = A^(x % φ(C) + φ(C)) (mod C)  (x >= φ(C)) 

定理1 应用:
    ∑(i=1,m)φ(i*n) = φ(pi) * ∑(i=1,m)φ(i*n/pi) + ∑(i=1,m/pi)φ(i*n) ; (n无平方因子数)

*/

 

HDU 5728 - PowMod

标签:

原文地址:http://www.cnblogs.com/nicetomeetu/p/5701852.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!