2019.9.1——nanjin網絡賽[B. super_log]

問題蟲洞: 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;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章