快速幂加同余模

2^x mod n = 1

 HDU - 1395 

Give a number n, find the minimum x(x>0) that satisfies 2^x mod n = 1. 

InputOne positive integer on each line, the value of n. 
OutputIf the minimum x exists, print a line with 2^x mod n = 1. 

Print 2^? mod n = 1 otherwise. 

You should replace x and n with specific numbers. 
Sample Input

2
5

Sample Output

2^? mod 2 = 1
2^4 mod 5 = 1

#include <cstdio>
int Powermod(int a,int b,int c)
{
    int ans=1;
    a=a%c;
    while (b) {
        if (b&1)
        ans=ans*a%c;
        a=a*a%c;
        b>>=1;
    }
    return ans;
}

int main()
{
    int n;
    while (~scanf("%d",&n)) {
        if (n%2==0||n==1) {
            printf("2^? mod %d = 1\n",n);
            continue;    
        }
        for (int i=1;;i++) {
            if (Powermod(2,i,n)==1) {
                printf("2^%d mod %d = 1\n",i,n);
                break;    
            }
        }    
    }
    return 0;
}

这道题虽然题目字少,但是对于数论的初学者来说还是有难度的。因为这道题目涉及到了快速幂加上同余模的算法,代码中的核心部分Powermod是一个比较简洁的写法,还有一些比较清晰但是代码量多的写法。

这里附上代码以及推荐阅读的博客:

    private static int cifang3(int a, int b) {
        int s = 1;
        while (b > 0) {
            if (b % 2 == 1) {
                s = s % 1000;
                a = a % 1000;
                s = s * a;
            }
            a = a % 1000;
            a = a * a;
            b = b >> 1;
        }
        return s% 1000;
    }

https://blog.csdn.net/java_c_android/article/details/55802041

这个博客写得很清楚了,对于同余定理和快速幂不熟悉的同学们可以阅读一下。

对于同余定理的理解,我只说最后一行是怎么得来的,你可以看到第一行的末尾,已经存在两数乘积然后模m的形式了,这时候就直接将a%m看成一个整体,套用同余定理的公式就可以了。

这个东西最好记住,不然题目没法理解,真的。

对于快速幂来说,你可以把他们想象成一个一个待处理的瓜子一样,需要挨个地嗑。首先把他转换成二进制,这时候你就可以看到,哪些位是需要计算,哪些位是不需要计算的了。

对于乘的倍数来说,这是满算,所以当一位上有一的时候,你得照着它本来的值进行计算,而不是按照进制幂指数减一再乘。这基本上就是同余模和快速幂了。

至于同余模加快速幂你最好有个抽象的理解,也可以一步一步的演算,虽然这样也可能理解不了本质,所以抽象一点,我算的就是同余定理,我要的也是他的同余数,只要按照正确的式子j进行

计算就能得到正确的答案,前提是代码得出的式子是建立的同余定理的基础上的,具体详见第一块代码的Powermod部分。

转载于:https://www.cnblogs.com/xyqxyq/p/9439300.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值