https://nanti.jisuanke.com/t/41299

题意:求aa a... 总共b个a的乘积(mod m)

坑:a==1 结果为1 mod m

广义欧拉降幂:

ab % p  = a( b%φ(p)) %p         (b < φ(p))

ab % p = a(b%φ(p)+φ(p)) %p   (b >= φ(p))

  1 #include<cstdio>
  2 #include<iostream>
  3 #include<algorithm>
  4 #include<queue>
  5 using namespace std;
  6 #define ll long long
  7 const int N = 1e6+10;
  8 ll m;
  9 int phi[N],vis[N],prime[N];
 10 int cnt;
 11 void getphi(){
 12     cnt = 0;
 13     for(int i = 1;i < N;i++) vis[i] = 0;
 14     phi[1] = 1;
 15     vis[1] = 1;
 16     for(int i = 2;i < N;i++){
 17         if(vis[i]==0){
 18             prime[cnt++] = i;
 19             phi[i] = i-1;
 20         }
 21         for(int j = 0;j < cnt&&i*prime[j]<N;j++){
 22             vis[i*prime[j]] = 1;
 23             if(i%prime[j]==0){
 24                 phi[i*prime[j]]=phi[i]*prime[j];
 25                 break;
 26             }
 27             else phi[i*prime[j]]=phi[i]*phi[prime[j]];
 28         }
 29     }
 30 }
 31 ll mul(ll a,ll b,ll p){
 32     ll ans = 1;
 33     ll pos = a%p;
 34     while(b){
 35         if(b&1){
 36             ans = ans * pos;
 37             ans = ans%p;
 38         }
 39         pos = pos*pos;
 40         pos = pos%p;
 41         b=b/2;
 42     }
 43     return ans;
 44 }
 45 ll quick_mul(ll a,ll b){
 46     ll ans = 1;
 47     ll pos = a;
 48     while(b){
 49         if(b&1) ans = ans*pos;
 50         pos = pos*pos;
 51         b>>=1;
 52     }
 53     return ans;
 54 }
 55 bool check(ll a,ll b,int j){//compare  此处是总共b层a的幂与j比较,而不是a的b次方与j比较)
 56     ll p = j;
 57     if(a==1) return 1>=p;
 58     else{
 59         if(b==0) return 1>= p;
 60         else if(b==1) return a>=p;
 61         else if(b==2){
 62             if(a>=8) return 1;
 63             else return quick_mul(a,a)>=p;
 64         }
 65         else if(b==3){
 66             if(a>=3) return 1;
 67             else return 16>=p;
 68         }
 69         else if(b==4){
 70             if(a>=3) return 1;
 71             else return 65536>=p;
 72         }
 73         else return 1;
 74     }
 75 
 76 }
 77 ll get(ll a,ll b,ll p){
 78     if(p==1) return 0;
 79     if(a==1||b==0) return 1;
 80     if(b==1) return a%p;
 81     ll bb;
 82     if(check(a,b-1,phi[p])) {
 83         bb = get(a,b-1,phi[p])+phi[p];
 84     }
 85     else {
 86         bb = get(a,b-1,phi[p]);
 87     }
 88     return mul(a,bb,p);
 89 }
 90 
 91 int main()
 92 {
 93 
 94     int t;
 95     ll a,b;
 96     scanf("%d",&t);
 97     getphi();
 98     //for(int i = 1;i <= N;i++) cout<<i<<":"<<phi[i]<<endl;
 99     while(t--){
100         scanf("%lld%lld%lld",&a,&b,&m);
101         if(m==1) printf("0\n");
102         else if(a==1||b==0) printf("1\n");
103         else if(b==1) printf("%lld\n",a%m);
104         else{
105             printf("%lld\n",get(a,b,m)%m);
106         }
107     }
108     return 0;
109 }
View Code

 

posted @ 2019-09-03 19:56  Obliviate  阅读(111)  评论(0)    收藏  举报