zoukankan      html  css  js  c++  java
  • 洛谷 P5091 【模板】欧拉定理

    题目

    题目描述

    给你三个正整数,a,m,ba,m,b,你需要求:
    a^b mod 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 mod 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 }

     

     

    为何要逼自己长大,去闯不该闯的荒唐
  • 相关阅读:
    (PHP)redis Zset(有序集合 sorted set)操作
    (PHP)redis Set(集合)操作
    (PHP)redis Hash(哈希)操作
    (PHP)redis String(字符串)操作
    (PHP)redis List(列表)操作
    PHP连接 redis
    PHP json 对象 数组互相转换
    循环节长度 蓝桥杯
    三羊献瑞 蓝桥杯
    立方变自身
  • 原文地址:https://www.cnblogs.com/zjzjzj/p/11321008.html
Copyright © 2011-2022 走看看