zoukankan      html  css  js  c++  java
  • Codevs 1200 同余方程 2012年NOIP全国联赛提高组

    1200 同余方程 2012年NOIP全国联赛提高组
    时间限制: 1 s
    空间限制: 128000 KB
    题目等级 : 钻石 Diamond
    题目描述 Description
    求关于 x 同余方程 ax ≡ 1 (mod b)的最小正整数解。
    输入描述 Input Description
    输入只有一行,包含两个正整数 a, b,用 一个 空格隔开。
    输出描述 Output Description
    输出只有一行包含一个正整数x0,即最小正整数解,输入数据保证一定有解。
    样例输入 Sample Input
    3 10
    样例输出 Sample Output
    7
    数据范围及提示 Data Size & Hint
    【数据范围】
    对于 40% 的数据, 2 ≤b≤ 1,000 ;
    对于 60% 的数据, 2 ≤b≤ 50,000,000
    对于 100% 的数据, 2 ≤a, b≤ 2,000,000,000
    分类标签 Tags
    欧几里德定理 数论 大陆地区 NOIP全国联赛提高组 2012年

    /*
    求关于x的模线性方程
    ax≡1(mod b)的最小正整数解.
    我们可以转化求不定方程ax+by=1的根来求.
    若方程有整数解 则gcd(a,b)=1(即 1|gcd(a,b)). 
    求出一组解(x0,y0).
    然后特殊地此题gcd(a,b)=1.
    so x+b/gcd(a,b)等价于x+b.
    又因为是mod b的剩余系中.
    so ans=(x+b)%b. 
    观察此式 可知x是a关于mod y剩余系下的逆元.
    若b为质数 则由费马小定理
    a^(p-1)=1,可知a^(p-2)为逆元.
    */
    #include<iostream>
    #include<cstdio>
    #define LL long long
    using namespace std;
    LL x,y;
    inline int read()
    {
        int x=0,f=1;char ch=getchar();
        while(ch<'0'||ch>'9') {if(ch=='-') f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9') x=x*10+ch-48,ch=getchar();
        return x*f;
    }
    void ex_gcd(LL a,LL b,LL &x,LL &y)
    {
        if(!b) {x=1,y=0;return ;}
        else ex_gcd(b,a%b,y,x),y-=(a/b)*x;
    }
    int main()
    {
        LL a,b;
        a=read(),b=read();
        ex_gcd(a,b,x,y);
        cout<<(x+b)%b;
        return 0;
    }
    /*
    看到网上有这种做法.
    挺巧妙的.
    由欧拉函数性质:a^phi(b)%b=1.
    so a*a^(phi(b)-1)%b=1.
    so 该方程的解为x=a^(phi(b)-1).
    so 在mod b剩余系下
    最小正整数解为x=a^(phi(b)-1)%b.
    然后枚举因子求phi(b),快速幂求a^(phi(b)-1)%b.
    特殊地若b为质数
    由欧拉函数性质phi(b)=b-1.
    即求a^(b-2)%b.(和费马小定理的结论一样....) 
    */
    #include<iostream>
    #include<cstdio>
    #define LL long long
    using namespace std;
    LL x,y,s,ans,a,b;
    inline LL read()
    {
        LL x=0,f=1;char ch=getchar();
        while(ch<'0'||ch>'9') {if(ch=='-') f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9') x=x*10+ch-48,ch=getchar();
        return x*f;
    }
    void eu()
    {
        LL n=b;
        ans=n;
        for(int i=2;i*i<=n;i++)
        {
            if(!(n%i))
            {
                while(!(n%i)) n/=i;
                ans=ans/i*(i-1);
            }
        }
        if(n>1) ans=ans/n*(n-1);
    }
    LL mi(LL a,LL p)
    {
        LL tot=1;
        while(p)
        {
            if(p&1) tot=tot*a%b;
            a=a*a%b;
            p>>=1;
        }
        return tot;
    }
    int main()
    {
        a=read(),b=read();
        eu();
        ans=mi(a,ans-1)%b;
        cout<<ans;
        return 0;
    }
  • 相关阅读:
    Python使用print打印时,展示内容不换行
    二进制、八进制、十进制和十六进制的相互转化(图解)
    IDEA 配置背景颜色(豆沙绿)
    Linux下脚本文件第一行的作用
    IDEA 注释模板配置
    IDE 常用配置
    Python 运算符
    Python 基础
    Chrome 浏览器快捷键
    正则表达式
  • 原文地址:https://www.cnblogs.com/nancheng58/p/10068157.html
Copyright © 2011-2022 走看看