ACM_数学

同余

a x ≡ b ( m o d m ) ax\equiv b(mod m) axb(modm)   其中 d = g c d ( a , m ) ∣ b d=gcd(a,m)|b d=gcd(a,m)b

x x x d d d个模 m m m不同余的解

欧拉降幂

在这里插入图片描述
广义欧拉降幂:只要判断b与 ϕ ( p ) \phi(p) ϕ(p)的大小关系:
a b = a b % ϕ ( p ) a^{b}=a^{b\%\phi(p)} ab=ab%ϕ(p) b < ϕ ( p ) b<\phi(p) b<ϕ(p)
a b = a b % ϕ ( p ) + ϕ ( p ) a^{b}=a^{b\%\phi(p)+\phi(p)} ab=ab%ϕ(p)+ϕ(p) b ≥ ϕ ( p ) b\geq \phi(p) bϕ(p)

模板题

在这里插入图片描述

#include <bits/stdc++.h>

using namespace std;

typedef long long LL;

LL a, b, c, mod = 1e9+7;

LL qmi(LL a, LL b, LL p) {
    LL res = 1;
    while (b) {
        if (b & 1)  res = 1ll * res * a % p;
        b >>= 1;
        a = 1ll * a * a % p;
    }
    return res;
}

LL phi(LL x) {  //返回x的欧拉函数值
    LL res = x;
    for (LL i = 2; i <= x / i; i ++) {
        if (x % i == 0) {
            res = res / i * (i - 1);
            while (x % i == 0)  x /= i;
        }
    }
    if (x > 1)  res = res / x * (x - 1);
    return res;
}

LL sol(LL a, LL b, LL p) {  //欧拉降幂
    LL t = phi(p);
    if (__gcd(a, p) > 1 && b >= t)    return qmi(a, b % t + t, p);
    else return qmi(a, b % t, p) % p;

}

int main() {
     while(~scanf("%lld%lld%lld", &a, &b, &c)) {
        LL t = sol(b, c, phi(mod));
        printf("%lld\n",sol(a, t, mod));
    }
    return 0;
}

Gym - 101550E

在这里插入图片描述

求 n ( n − 1 ) ( n − 2 ) . . . 2 1 % m 求n^{(n-1)^{(n-2)^{...^{2^{1}}}}}\%m n(n1)(n2)...21%m的值

A C 代码在幂数 b < 模数 m 时,直接用快速幂可以 A C ,但是用欧拉降幂继续递归求解会 W A 。有解释说 b < ϕ ( m ) 时不满足欧拉降幂的条件。 AC代码在幂数b<模数m时,直接用快速幂可以AC,但是用欧拉降幂继续递归求解会WA。有解释说b<\phi(m)时不满足欧拉降幂的条件。 AC代码在幂数b<模数m时,直接用快速幂可以AC,但是用欧拉降幂继续递归求解会WA。有解释说b<ϕ(m)时不满足欧拉降幂的条件。这种情况不就是 b < ϕ ( p ) b<\phi(p) b<ϕ(p)的情况吗,但用这种写法确实会WA

#include <bits/stdc++.h>


#define MOD(a,b) a>=b?a%b+b:a

using namespace std;

typedef long long LL;
typedef long long ll;

LL a, b, c, mod = 1e9+7;

LL qmi(LL a, LL b, LL p) {
    LL res = 1;
    while (b) {
        if (b & 1)  res = 1ll * res * a % p;
        b >>= 1;
        a = 1ll * a * a % p;
    }
    return res;
}

LL phi(LL x) {  //返回x的欧拉函数值
    LL res = x;
    for (LL i = 2; i <= x / i; i ++) {
        if (x % i == 0) {
            res = res / i * (i - 1);
            while (x % i == 0)  x /= i;
        }
    }
    if (x > 1)  res = res / x * (x - 1);
    return res;
}

LL sol(LL a, LL p) {   //AC
    if (p == 1) return 0;	//模数为1
    if (a == 1) return 1;	//底数为1
    else if (a == 2)    return 2 % p;
    else if (a == 3)    return 9 % p;
    else if (a == 4)    return 262144 % p;
    
    //5^262144>1e9,超过模数的最大取值,用欧拉降幂
    LL t = phi(p);
    LL b = sol(a - 1, t);
    return qmi(a, b % t + t, p);
}

LL sol2(LL a, LL p) {   //WA
    if (p == 1) return 0;
    if (a == 1) return 1;

    LL t = phi(p);
    LL b = sol(a - 1, t);
    if (b < t)return qmi(a, b % t, p);
    return qmi(a, b % t + t, p);
}

int main() {
    LL n, m;
    cin >> n >> m;
    cout << sol(n, m);
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值