参考博客:欧拉降幂和广义欧拉降幂
定理:
欧拉定理:若n,a为正整数,且n,a互质,则: 。
由此得出降幂公式:
。
更具体:
Code:(欧拉函数+快速幂)
ll phi(ll n) {
ll ans = 1;
for (ll i = 2; i*i <= n; i++) {
if (n%i == 0) {
n /= i;
ans *= i - 1;
while (n%i == 0) {
n /= i;
ans *= i;
}
}
}
if (n > 1) ans *= n - 1;
return ans;
}
ll multiply(ll a, ll b, ll mod)
{
ll ans = 1;
while (b)
{
if (b & 1)
{
ans = ((ans%mod)*(a%mod)) % mod;
b--;
}
b /= 2;
a = ((a%mod)*(a%mod)) % mod;
}
return ans;
}
例题:
题意:
A(m) = mod (1e9+7),m为2的层数。T组数据(T<=10),每组输入包含一个m(1<=m<=10)。
链接:Ackerman(学校内网)
分析:
指数会爆long long,所以需要欧拉降幂。需要注意的是,在计算指数的时候也会用到快速幂,此时模数需要迭代。
code:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MAX = 100 + 10;
const ll MOD = 1e9 + 7;
int n;
ll f[MAX];
ll phi(ll n) {
ll ans = 1;
for (ll i = 2; i*i <= n; i++) {
if (n%i == 0) {
n /= i;
ans *= i - 1;
while (n%i == 0) {
n /= i;
ans *= i;
}
}
}
if (n > 1) ans *= n - 1;
return ans;
}
ll multiply(ll a, ll b, ll mod)
{
ll ans = 1;
while (b)
{
if (b & 1)
{
ans = ((ans%mod)*(a%mod)) % mod;
b--;
}
b /= 2;
a = ((a%mod)*(a%mod)) % mod;
}
return ans;
}
//计算指数
ll cul(int x, ll p)
{
ll val = 4;
if (x == 1) {
return val;
}
//注意模数需要迭代
val = multiply(2, cul(x - 1, phi(p)), p);
return val % p + p;
}
int main()
{
int T;
scanf("%d", &T);
f[1] = 4;
//phi(1e9+7)=1e9+6
for (int i = 2; i <= 10; i++) {
f[i] = multiply(2, cul(i - 1, MOD - 1), MOD);
}
while (T--)
{
scanf("%d", &n);
printf("%lld\n", f[n]);
}
return 0;
}