問題蟲洞: B. super_log
黑洞內窺:
定義一個式子:
鍵入a,b,m;
求一個最小的x,滿足上式,然後輸出x%m;
思維光年:
易推導得出:
x = a^a^a^.........^a^a(一共b個a的高階冪)%m;
然後就是歐拉降冪了:
一開始我的做法:
因爲歐拉降冪有條件限制,一開始忘記了這個限制條件,導致瘋狂的wa(這時我用的是for循環處理),
後來即使我發現了是限制條件的問題,由於代碼能力太弱,
不會用for循環繼續限制這個條件,並且本人對遞歸也比較迷~~~
遂將idea轉達隊友,然後隊友找個板子就A掉了,,!(我太難了~~~)
ACcode:
#include<bits/stdc++.h>
#define Mod(a,b) a<b?a:a%b+b //重定義取模,按照歐拉定理的條件
#define LL long long
#define N 100010
using namespace std;
LL n,q,m,a,b,T;
map<LL,LL> mp;
LL qpow(LL x,LL n,LL m)
{
LL res=1;
while(n)
{
if (n&1)
res=Mod(res*x,m),n--;
x=Mod(x*x,m);
n>>=1;
}
return res;
}
LL phi(LL k)
{
LL i,s=k,x=k;
if (mp.count(k))
return mp[x]; //記憶化存儲
for(i = 2; i * i <= k; i++) //歐拉函數
{
if(k % i == 0)
s = s / i * (i - 1);
while(k % i == 0)
k /= i;
}
if(k > 1)
s = s / k * (k - 1);
mp[x]=s;
return s;
}
LL solve(LL l,LL r,LL m)
{
if (l==r||m==1)
return Mod(a,m); //限制條件
return qpow(a,solve(l+1,r,phi(m)),m); //往上遞歸
}
int main()
{
scanf("%d",&T);
while(T--)
{
scanf("%lld%lld%lld",&a,&b,&m);
if(m == 1)
printf("0\n");
else if(b == 0 || a == 1)
printf("1\n");
else
printf("%lld\n",solve(1,b,m) % m);
}
return 0;
}