洛谷 P5091 【模板】欧拉定理

题目

题目描述

给你三个正整数,a,m,ba,m,b,你需要求:
a^b \bmod mabmodm

输入格式

一行三个整数,a,m,ba,m,b

输出格式

一个整数表示答案

输入输出样例

输入 #1复制
2 7 4
输出 #1复制
2
输入 #2复制
998244353 12345 98765472103312450233333333333
输出 #2复制
5333

说明/提示

注意输入格式,a,m,ba,m,b 依次代表的是底数、模数和次数

样例1解释:
2^4 \bmod 7 = 224mod7=2
输出2

数据范围:

对于全部数据:
1≤a≤10^91a109
1≤b≤10^{20000000}1b1020000000
1≤m≤10^61m106

 

分析

 

  • 首先,我们需要知道欧拉定理,扩展欧拉定理
  • 欧拉定理 aφ(m≡ mod m
  • 扩展欧拉定理 bφ(m),a^≡ a^(mod φ(m)φ(mmod m
  • 那我们来证明下欧拉定理
  • 定义一个n=φ(m)
  • 设x1,x2,x3...xn是小于m与m互质的数
  • 然后我们再设k为与m互质的数 gcd(k,m)=1
  • 那么再构成一个数列A{kx1,kx2,kx3...kxn}
  • 我们尝试证明A中有两个数mod m是相等的
  1. 假设 ak≡bk (mod m)
  2. ak-bk=qm q为m的倍数 
  3. (a-b)k=qm 所以左边mod m是等于0的
  4. 但是k与m互质所以是不成立的 证毕
  • 我们再证明A中所以数mod m 都是与 m 互质的
  1. 首先 kx=k*x
  2. k是与m互质的 x也是与m互质的
  3. 所以gcd(k,m)=1,gcd(x,m)=1
  4. 所以k*x都不包含m的因子
  5. 也就是说k*x/m是个最简分数
  6. gcd(kx,m)=1,gcd(kx%m,m)=1;欧几里得定理 证毕
  • 还有就是如何求欧拉函数
  • 欧拉筛是n
  • 我们筛合数就是nsqrt(n)

 

代码

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cmath>
 4 using namespace std;
 5 int read(int mod)
 6 {
 7     int s=0,w=1,flag=0;
 8     char c=getchar();
 9     while (c<'0'||c>'9') if (c=='-') w=-1; else c=getchar();
10     while (c<='9'&&c>='0') 
11     {
12        s=(s*10+c-'0');
13        if (s>=mod)
14        {
15             s%=mod;
16             flag=1;
17        }
18        c=getchar();
19     }
20     if (flag) s+=mod;
21     return s;
22 }
23 long long ksm(long long a,long long b,long long mod)
24 {
25     long long x=a,ans=1;
26     while (b)
27     {
28         if (b&1!=0) ans=ans*x%mod;
29         x=x*x%mod;
30         b>>=1;
31     }
32     return ans;
33 } 
34 int main ()
35 {
36     int a,b,m;
37     cin>>a>>m;
38     int tmp=m,phi=m;
39     for (int i=2;i*i<=m;++i)
40     {
41         if (tmp%i==0)
42         {
43             phi=phi-phi/i;
44             while (tmp%i==0)
45             {
46                 tmp/=i;
47             }
48         }
49     }
50     if (tmp>1) phi=phi-phi/tmp;
51     b=read(phi);
52     cout<<ksm(a,b,m);
53 }

 

 

 

转载于:https://www.cnblogs.com/zjzjzj/p/11321008.html

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值