数论基本定理典型例题

1.  HDU-2973(威尔逊定理)

The math department has been having problems lately. Due to immense amount of unsolicited automated programs which were crawling across their pages, they decided to put Yet-Another-Public-Turing-Test-to-Tell-Computers-and-Humans-Apart on their webpages. In short, to get access to their scientific papers, one have to prove yourself eligible and worthy, i.e. solve a mathematic riddle. 


However, the test turned out difficult for some math PhD students and even for some professors. Therefore, the math department wants to write a helper program which solves this task (it is not irrational, as they are going to make money on selling the program). 

The task that is presented to anyone visiting the start page of the math department is as follows: given a natural n, compute 

 


where [x] denotes the largest integer not greater than x.

Input

The first line contains the number of queries t (t <= 10^6). Each query consist of one natural number n (1 <= n <= 10^6).

Output

For each n given in the input output the value of Sn.

Sample Input

13
1
2
3
4
5
6
7
8
9
10
100
1000
10000

Sample Output

0
1
1
2
2
2
2
3
3
4
28
207
1609

思路:由威尔逊定理p|(p-1)!+1,当且仅当p是质数。所以本题只要判断区间内有多少质数即可。

/**

**/
#include <cstdio>
#include <stack>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <iostream>
#include <map>
#include <vector>
#include <queue>
#include <set>
#define eps 1e-8
typedef long long ll;
const double PI = acos(-1.0);
const int maxn = 3e6+10;
const int INF = 0x3f3f3f;
const ll linf = 0x3f3f3f3f3f3f3f3f;
const int mod = 1e9+7;
using namespace std;
int vis[maxn+5];
int cnt[maxn];
void init()
{
    int n = maxn;
    memset(vis, 0, sizeof vis);
    memset(cnt,0,sizeof cnt);
    for(int i = 2; i<=n; i++)
    {
        if(vis[i])
            continue;
       //isprime[i] = 1;
        for(int j = i; j<=n/i; j++)
            vis[i*j] = 1;
    }
    cnt[0] = 0;
    for(int i = 1; i<=1000000; i++)
    {
        int k = 3*i+7;
        cnt[i] = cnt[i-1];
        if(!vis[k])
            cnt[i]++;
    }
}
int main()
{
    ios::sync_with_stdio(false);
    int T;
    cin>>T;
    init();
    while(T--)
    {
        int n;
        cin>>n;
        cout<<cnt[n]<<endl;
    }

    return 0;
}

 2.  HDU 3501   (互质数的和)

Given a positive integer N, your task is to calculate the sum of the positive integers less than N which are not coprime to N. A is said to be coprime to B if A, B share no common positive divisors except 1.

Input

For each test case, there is a line containing a positive integer N(1 ≤ N ≤ 1000000000). A line containing a single 0 follows the last test case.

Output

For each test case, you should print the sum module 1000000007 in a line.

Sample Input

3
4
0

Sample Output

0
2

思路:

假设n以内与n互素的数之和为res:

若(a,n) = 1,则(n-a,n) = 1.又知n以内与n互素的数一共有phi个,故列出两个等式

res = a1+a2+……+aphi

res = n-a1 + n-a2 +……+ n-aphi

所以得res = phi*n/2

所以答案为n*(n+1)/2-n*phi(n)/2

/**

**/
#include <cstdio>
#include <stack>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <iostream>
#include <map>
#include <vector>
#include <queue>
#include <set>
#define eps 1e-8
typedef long long ll;
const double PI = acos(-1.0);
const int maxn = 1e6;
const int INF = 0x3f3f3f;
const ll linf = 0x3f3f3f3f3f3f3f3f;
const int mod = 1e9+7;
using namespace std;
int euler(int n)
{
    int m = sqrt(n) + 0.5;
    int ans = n;
    for (int i = 2; i <= m; ++i)
    if (n%i == 0)
    {
        ans = ans / i * (i - 1);
        while (n%i == 0) n /= i;
    }
    if (n > 1) ans = ans / n *(n - 1);
    return ans;
}
int main()
{
    ios::sync_with_stdio(false);
    int n;
    while(cin>>n && n)
    {
        int ph = euler(n);
        ll ans = 1ll*n*(n-1)/2 - 1ll*n*ph/2;
        cout<<ans%mod<<endl;
    }

    return 0;
}

3. ICPC2018焦作网赛(费马降幂)

There are NN children in kindergarten. Miss Li bought them NN candies. To make the process more interesting, Miss Li comes up with the rule: All the children line up according to their student number (1...N)(1...N), and each time a child is invited, Miss Li randomly gives him some candies (at least one). The process goes on until there is no candy. Miss Li wants to know how many possible different distribution results are there.

Input

The first line contains an integer TT, the number of test case.

The next TT lines, each contains an integer NN.

1 \le T \le 1001≤T≤100

1 \le N \le 10^{100000}1≤N≤10100000

Output

For each test case output the number of possible results (mod 1000000007).

样例输入复制

1
4

样例输出复制

8

思路:

首先很好想的是,这个题答案是2^(n-1),麻烦就麻烦在n太大,快速幂也无法解决。

所以可以使用费马小定理进行降幂:a^(p-1) = 1(mod p)

#include <cstdio>
#include <stack>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <iostream>
#include <map>
#include <vector>
#include <queue>
#include <set>
#define eps 1e-8
typedef long long ll;
const double PI = acos(-1.0);
const int maxn = 1e6;
const int INF = 0x3f3f3f;
const ll linf = 0x3f3f3f3f3f3f3f3f;
const int mod = 1e9+7;
using namespace std;
char a[maxn];
ll qsm(ll a, ll b)
{
    ll ans = 1;
    a%=mod;
    while(b)
    {
        if(b&1)
            ans = ans*a%mod;
        a = a*a%mod;
        b>>=1;
    }
    return ans;
}
int main()
{
    //ios::sync_with_stdio(false);
    int T;
    cin>>T;
    while(T--)
    {
        scanf("%s",a);
        int len = strlen(a);
        ll n = 0;
        for(int i = 0; i<len; i++)
            n = (n*10+a[i]-'0')%(mod-1);
        cout<<qsm(2,n-1)%mod<<endl;
    }

    return 0;
}

4. codeforces 17D (欧拉降幂)

D. Notepad

time limit per test

2 seconds

memory limit per test

64 megabytes

input

standard input

output

standard output

Nick is attracted by everything unconventional. He doesn't like decimal number system any more, and he decided to study other number systems. A number system with base b caught his attention. Before he starts studying it, he wants to write in his notepad all the numbers of length n without leading zeros in this number system. Each page in Nick's notepad has enough space for c numbers exactly. Nick writes every suitable number only once, starting with the first clean page and leaving no clean spaces. Nick never writes number 0 as he has unpleasant memories about zero divide.

Would you help Nick find out how many numbers will be written on the last page.

Input

The only input line contains three space-separated integers bn and c (2 ≤ b < 10106, 1 ≤ n < 10106, 1 ≤ c ≤ 109). You may consider that Nick has infinite patience, endless amount of paper and representations of digits as characters. The numbers doesn't contain leading zeros.

Output

In the only line output the amount of numbers written on the same page as the last number.

Examples

input

Copy

2 3 3

output

Copy

1

input

Copy

2 3 4

output

Copy

4

Note

In both samples there are exactly 4 numbers of length 3 in binary number system. In the first sample Nick writes 3 numbers on the first page and 1 on the second page. In the second sample all the 4 numbers can be written on the first page.

思路:

思路简单清晰,即求b^(n-1) *(b-1) %c,问题还是n太大,所以这个时候考虑欧拉降幂

a^{b} \equiv \left\{\begin{matrix}a^{b}, b<\phi (p) \\ a^{b\%\phi (p)+\phi(p)},b>=\phi(p) \end{matrix}\right.(mod\ p)

#include <cstdio>
#include <stack>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <iostream>
#include <map>
#include <vector>
#include <queue>
#include <set>
#define eps 1e-8
typedef long long ll;
const double PI = acos(-1.0);
const int maxn = 1e6;
const int INF = 0x3f3f3f;
const ll linf = 0x3f3f3f3f3f3f3f3f;
const int mod = 1e9+7;
using namespace std;
string B,N;
ll c;
int euler(int n)
{
    int m = sqrt(n) + 0.5;
    int ans = n;
    for (int i = 2; i <= m; ++i)
    if (n%i == 0)
    {
        ans = ans / i * (i - 1);
        while (n%i == 0) n /= i;
    }
    if (n > 1) ans = ans / n *(n - 1);
    return ans;
}
ll qsm(ll a,ll b, ll p)
{
    ll ans = 1;
    while(b)
    {
        if(b&1)
            ans = ans*a%p;
        a = a*a%p;
        b >>= 1;
    }
    return ans;
}
int main()
{
    ios::sync_with_stdio(false);
    while(cin>>B>>N>>c)
    {
        ll phi = euler(c);
        int lenb = B.length();
        ll b = 0;
        for(int i = 0; i<lenb; i++)
            b = (b*10+B[i]-'0')%c;
        ll n = 0;
        int lenn = N.length();
        int f = 0;
        for(int i = 0; i<lenn; i++)
        {
            n = n*10+N[i]-'0';
            if(n>=phi+1)
            {
                f = 1;
                n %= phi;
            }
        }
        if(f)
            n += phi;
        ll ans = (qsm(b,n-1,c)*(b-1)+c)%c;
        if(!ans)
            ans = c;
        cout<<ans<<endl;
    }

    return 0;
}

 5.BZOJ 3884(欧拉降幂)

根据一些书上的记载,上帝的一次失败的创世经历是这样的:

第一天,  上帝创造了一个世界的基本元素,称做“元”。

第二天,  上帝创造了一个新的元素,称作“α”。“α”被定义为“元”构成的集合。容易发现,一共有两种不同的“α”。

第三天,  上帝又创造了一个新的元素,称作“β”。“β”被定义为“α”构成的集合。容易发现,一共有四种不同的“β”。

第四天,  上帝创造了新的元素“γ”,“γ”被定义为“β”的集合。显然,一共会有16种不同的“γ”。

如果按照这样下去,上帝创造的第四种元素将会有65536种,第五种元素将会有2^65536种。这将会是一个天文数字。

然而,上帝并没有预料到元素种类数的增长是如此的迅速。他想要让世界的元素丰富起来,因此,日复一日,年复一年,他重复地创造着新的元素……

然而不久,当上帝创造出最后一种元素“θ”时,他发现这世界的元素实在是太多了,以致于世界的容量不足,无法承受。因此在这一天,上帝毁灭了世界。

至今,上帝仍记得那次失败的创世经历,现在他想问问你,他最后一次创造的元素“θ”一共有多少种?

上帝觉得这个数字可能过于巨大而无法表示出来,因此你只需要回答这个数对p取模后的值即可。

你可以认为上帝从“α”到“θ”一共创造了10^9次元素,或10^18次,或者干脆∞次。

一句话题意:

 

 

 

Input

接下来T行,每行一个正整数p,代表你需要取模的值

 

Output

T行,每行一个正整数,为答案对p取模后的值

 

Sample Input

3 2 3 6

Sample Output

0 1 4

Hint

 

对于100%的数据,T<=1000,p<=10^7

思路:

运用欧拉降幂,其实对任何一个数n不停地取phi,只要最多logn次就能取成1,所以这个还是有极限的,递归求值,当指数phi变成1结束即可。注意快速幂时由于要保证欧拉降幂的条件,所以快速幂的所有取模也要写成a = a>=m?a%m+m:a

/**

**/
#include <cstdio>
#include <stack>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <iostream>
#include <map>
#include <vector>
#include <queue>
#include <set>
#define eps 1e-8
typedef long long ll;
const double PI = acos(-1.0);
const int maxn = 1e6;
const int INF = 0x3f3f3f;
const ll linf = 0x3f3f3f3f3f3f3f3f;
const int mod = 1e9+7;
using namespace std;
map<ll,ll>mp;
ll phi(ll x)
{
    if(mp[x])
        return mp[x];
    ll tmp = x,res = x;
    for(int i = 2; i*i<=x; i++)
    {
        if(x%i == 0)
        {
            res = res*(i-1)/i;
            while(x%i==0)
                x/=i;
        }
    }
    if(x>1)
        res = res*(x-1)/x;
    return mp[tmp] = res;
}
ll qsm(ll a, ll b, ll p)
{
    ll ans = 1;
    while(b)
    {
        if(b&1)
            ans = (ans*a)%p;
        a = (a*a)%p;
        b >>= 1;
    }
    return ans;
}
ll f(ll a, ll p)
{
    if(p == 1)
        return 1;
    return qsm(a,f(a,phi(p))+phi(p),p);
}
int main()
{
    ios::sync_with_stdio(false);
    int T;
    cin>>T;
    while(T--)
    {
        ll p;
        cin>>p;
        if(p == 1 || p == 0)
            cout<<0<<endl;
        else
            cout<<f(2,p)<<endl;
    }


    return 0;
}

6. HDU-3221(欧拉降幂)

Professor Brute is not good at algorithm design. Once he was asked to solve a path finding problem. He worked on it for several days and finally came up with the following algorithm: 


Any fool but Brute knows that the function “funny” will be called too many times. Brute wants to investigate the number of times the function will be called, but he is too lazy to do it. 

Now your task is to calculate how many times the function “funny” will be called, for the given a, b and n. Because the answer may be too large, you should output the answer module by P.

Input

There are multiple test cases. The first line of the input contains an integer T, meaning the number of the test cases. 

For each test cases, there are four integers a, b, P and n in a single line. 
You can assume that 1≤n≤1000000000, 1≤P≤1000000, 0≤a, b<1000000.

Output

For each test case, output the answer with case number in a single line.

Sample Input

3
3 4 10 3
4 5 13 5
3 2 19 100

Sample Output

Case #1: 2
Case #2: 11
Case #3: 12

 思路:这个题就是a^fib[n-3]*b^fib[n-2]%p,因为n很大,所以矩阵快速幂求fib的同时需要使用欧拉降幂

#include <cstdio>
#include <stack>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <iostream>
#include <map>
#include <vector>
#include <queue>
#include <set>
#define eps 1e-8
typedef long long ll;
const double PI = acos(-1.0);
const int maxn = 1e6;
const int INF = 0x3f3f3f;
const ll linf = 0x3f3f3f3f3f3f3f3f;
const int mod = 1e9+7;
using namespace std;
ll phi[maxn+5];
ll a,b,m,n;
struct Matrix
{
    ll a[2][2];
    Matrix()
    {
        memset(a,0,sizeof a);
    }
    Matrix operator* (const Matrix &p)
    {
        Matrix res;
        for(int i = 0; i<2; i++)
        {
            for(int j = 0; j<2; j++)
            {
                for(int k = 0; k<2; k++)
                {
                    res.a[i][j] += a[i][k]*p.a[k][j];
                    if(res.a[i][j]>phi[m])
                        res.a[i][j] = res.a[i][j]%phi[m]+phi[m];
                }
            }
        }
        return res;
    }
}ans,base;
Matrix qsm1(Matrix base, ll n)
{
    Matrix res;
    for(int i = 0; i<2; i++)
        res.a[i][i] = 1;
    while(n)
    {
        if(n&1)
            res = res*base;
        base = base*base;
        n >>= 1;
    }
    return res;
}
ll qsm2(ll a,ll b)
{
    ll ans = 1;
    while(b)
    {
        if(b&1)
            ans = ans*a%m;
        a = a*a%m;
        b >>= 1;
    }
    return ans;
}
void init1()
{
    int n = maxn;
    for(int i = 2; i<=n; i++)
        phi[i] = i;
    for(int i = 2; i<=n; i++)
    {
        if(phi[i] == i)
        {
            for(int j = i; j<=n; j += i)
                phi[j] = phi[j]/i*(i-1);
        }
    }
}
void init2()
{
    ans.a[0][0] = 1;
    ans.a[0][1] = 1;
    ans.a[1][0] = 0;
    ans.a[1][1] = 0;

    base.a[0][0] = 1;
    base.a[0][1] = 1;
    base.a[1][0] = 1;
    base.a[1][1] = 0;
}
int main()
{
    //ios::sync_with_stdio(false);
    int T;
    init1();
    cin>>T;
    int tt = 1;
    while(T--)
    {
        cin>>a>>b>>m>>n;
        printf("Case #%d: ",tt++);
        if(n == 1)
        {
            cout<<a%m<<endl;
            continue;
        }
        if(n == 2)
        {
            cout<<b%m<<endl;
            continue;
        }
        if(n == 3)
        {
            cout<<a*b%m<<endl;
            continue;
        }
        if(m == 1)
        {
            cout<<0<<endl;
            continue;
        }
        init2();
        ans = ans*qsm1(base,n-3);
        ll faca = ans.a[0][1];
        ll facb = ans.a[0][0];
        ll ansa = qsm2(a,faca);
        ll ansb = qsm2(b,facb);
        cout<<ansa*ansb%m<<endl;
    }

    return 0;
}

7.wannafly22A(裴蜀定理)

链接:https://ac.nowcoder.com/acm/contest/160/A?&headNav=www
来源:牛客网
 

时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 262144K,其他语言524288K
64bit IO Format: %lld

题目描述

有一个计数器,计数器的初始值为0,每次操作你可以把计数器的值加上a1,a2,...,an中的任意一个整数,操作次数不限(可以为0次),问计数器的值对m取模后有几种可能。

输入描述:

第一行两个整数n,m
接下来一行n个整数表示a1,a2,...,an
1≤n≤100
1≤m,a1,a2,...,an≤1000000000

输出描述:

输出一个整数表示答案

示例1

输入

复制

3 6
6 4 8

输出

复制

3

思路:由裴蜀定理,n个数构成的数的形式一定是k*d,d为gcd(a1~an),然后求一下数列kd关于m的循环节长度,为m/gcd(d,m)

/**

**/
#include <cstdio>
#include <stack>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <iostream>
#include <map>
#include <vector>
#include <queue>
#include <set>
#define eps 1e-8
typedef long long ll;
const double PI = acos(-1.0);
const int maxn = 1e3;
const int INF = 0x3f3f3f;
const ll linf = 0x3f3f3f3f3f3f3f3f;
const int mod = 1e9+7;
using namespace std;
ll a[maxn];
ll n,m;
ll gcd(ll a, ll b)
{
    return b==0?a:gcd(b,a%b);
}
int main()
{
    ios::sync_with_stdio(false);
    cin>>n>>m;
    for(int i = 0; i<n; i++)
        cin>>a[i];
    ll d = m;
    for(int i = 0; i<n; i++)
        d = gcd(d,a[i]);
    cout<<m/d<<endl;
    return 0;
}

 8.CodeForces-906D(欧拉降幂)

Priests of the Quetzalcoatl cult want to build a tower to represent a power of their god. Tower is usually made of power-charged rocks. It is built with the help of rare magic by levitating the current top of tower and adding rocks at its bottom. If top, which is built from k - 1 rocks, possesses power p and we want to add the rock charged with power wk then value of power of a new tower will be {wk}p.

Rocks are added from the last to the first. That is for sequence w1, ..., wm value of power will be

After tower is built, its power may be extremely large. But still priests want to get some information about it, namely they want to know a number called cumulative power which is the true value of power taken modulo m. Priests have n rocks numbered from 1 to n. They ask you to calculate which value of cumulative power will the tower possess if they will build it from rocks numbered l, l + 1, ..., r.

Input

First line of input contains two integers n (1 ≤ n ≤ 105) and m (1 ≤ m ≤ 109).

Second line of input contains n integers wk (1 ≤ wk ≤ 109) which is the power of rocks that priests have.

Third line of input contains single integer q (1 ≤ q ≤ 105) which is amount of queries from priests to you.

kth of next q lines contains two integers lk and rk (1 ≤ lk ≤ rk ≤ n).

Output

Output q integers. k-th of them must be the amount of cumulative power the tower will have if is built from rocks lk, lk + 1, ..., rk.

Example

Input

6 1000000000
1 2 2 3 3 3
8
1 1
1 6
2 2
2 3
2 4
4 4
4 5
4 6

Output

1
1
2
4
256
3
27
597484987

Note

327 = 7625597484987

思路:同前面,不再赘述 

#include <cstdio>
#include <stack>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <iostream>
#include <map>
#include <vector>
#include <queue>
#include <set>
#define eps 1e-8
typedef long long ll;
const double PI = acos(-1.0);
const int maxn = 1e6;
const int INF = 0x3f3f3f;
const ll linf = 0x3f3f3f3f3f3f3f3f;
const int mod = 1e9+7;
using namespace std;
int n;
ll w[maxn];
ll p;
map<ll,ll>mp;
ll phi(ll x)
{
    if(mp[x])
        return mp[x];
    ll tmp = x,res = x;
    for(int i = 2; i*i<=x; i++)
    {
        if(x%i == 0)
        {
            res = res*(i-1)/i;
            while(x%i==0)
                x/=i;
        }
    }
    if(x>1)
        res = res*(x-1)/x;
    return mp[tmp] = res;
}
ll qsm(ll a,ll b,ll p)
{
    ll res = 1;
    while(b)
    {
        if(b&1)
        {
            res = res*a;
            if(res>=p)
                res = res%p+p;
        }
        b >>= 1;
        a = a*a;
        if(a>=p)
            a = a%p+p;
    }
    return res;
}
ll solve(int l, int r, int m)
{
    if(l == r || m == 1)
        return w[l]>=m?w[l]%m+m:w[l];
    return qsm(w[l],solve(l+1,r,phi(m)),m);
}
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0),cout.tie(0);
    ll n,m;
    cin>>n>>m;
    for(int i = 1; i<=n; i++)
        cin>>w[i];
    int q;
    cin>>q;
    while(q--)
    {
        int l,r;
        cin>>l>>r;
        cout<<solve(l,r,m)%m<<endl;
    }
    return 0;
}

 9.2019ICPC南京网络赛(欧拉降幂)

In Complexity theory, some functions are nearly O(1)O(1), but it is greater then O(1)O(1). For example, the complexity of a typical disjoint set is O(nα(n))O(nα(n)). Here α(n)α(n) is Inverse Ackermann Function, which growth speed is very slow. So in practical application, we often assume α(n) \le 4α(n)≤4.

However O(α(n))O(α(n)) is greater than O(1)O(1), that means if nn is large enough, α(n)α(n) can greater than any constant value.

Now your task is let another slowly function log*log∗ xx reach a constant value bb. Here log*log∗ is iterated logarithm function, it means “the number of times the logarithm function iteratively applied on xx before the result is less than logarithm base aa”.

Formally, consider a iterated logarithm function log_{a}^*loga∗​ 

Find the minimum positive integer argument xx, let log_{a}^* (x) \ge bloga∗​(x)≥b. The answer may be very large, so just print the result xx after mod mm.

Input

The first line of the input is a single integer T(T\le 300)T(T≤300) indicating the number of test cases.

Each of the following lines contains 33 integers aa , bb and mm.

1 \le a \le 10000001≤a≤1000000

0 \le b \le 10000000≤b≤1000000

1 \le m \le 10000001≤m≤1000000

Note that if a==1, we consider the minimum number x is 1.

Output

For each test case, output xx mod mm in a single line.

Hint

In the 4-th4−th query, a=3a=3 and b=2b=2. Then log_{3}^* (27) = 1+ log_{3}^* (3) = 2 + log_{3}^* (1)=3+(-1)=2 \ge blog3∗​(27)=1+log3∗​(3)=2+log3∗​(1)=3+(−1)=2≥b, so the output is 2727 mod 16 = 1116=11.

样例输入复制

5
2 0 3
3 1 2
3 1 100
3 2 16
5 3 233

样例输出复制

1
1
3
11
223

思路:欧拉降幂,不再赘述。 

/**

**/
#include <cstdio>
#include <stack>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <iostream>
#include <map>
#include <vector>
#include <queue>
#include <set>
#define eps 1e-8
typedef long long ll;
const double PI = acos(-1.0);
const int maxn = 1e6;
const int INF = 0x3f3f3f;
const ll linf = 0x3f3f3f3f3f3f3f3f;
const int mod = 1e9+7;
using namespace std;
ll phi[maxn+5];
ll a,b,p;
void init()
{
    int n = maxn;
    for(int i = 0; i<=n; i++)
        phi[i] = i;
    for(int i = 2; i<=n; i++)
    {
        if(phi[i] == i)
        {
            for(int j = i; j<=n; j += i)
                phi[j] = phi[j]/i*(i-1);
        }
    }
}
ll qsm(ll a,ll b, ll p)
{
    ll ans = 1;
    while(b)
    {
        if(b&1)
        {
            ans = ans*a;
            if(ans>=p)
                ans = ans%p+p;
        }
        b >>= 1;
        a = a*a;
        if(a>=p)
            a = a%p+p;
    }
    return ans;
}
ll solve(int cnt,ll p)
{
    if(cnt == b || p == 1)
    {
        return a>=p?a%p+p:a;
    }
    return qsm(a,solve(cnt+1,phi[p]),p);
}
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0),cout.tie(0);
    init();
    int T;
    cin>>T;
    while(T--)
    {
        cin>>a>>b>>p;
        if(b == 0)
        {
            cout<<1%p<<endl;
            continue;
        }
        cout<<solve(1,p)%p<<endl;
    }

    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值