zoukankan      html  css  js  c++  java
  • 次方求模 http://acm.nyist.net/JudgeOnline/problem.php?pid=102

     

    次方求模

    时间限制:1000 ms  |  内存限制:65535 KB
    难度:3
     
    描述

    求a的b次方对c取余的值

     
    输入
    第一行输入一个整数n表示测试数据的组数(n<100)
    每组测试只有一行,其中有三个正整数a,b,c(1=<a,b,c<=1000000000)
    输出
    输出a的b次方对c取余之后的结果
    样例输入
    3
    2 3 5
    3 100 10
    11 12345 12345
    样例输出
    3
    1
    10481
    来源
    [张云聪]原创
    上传者
    张云聪
    #include<stdio.h>
    long long fun(long long a,long long b,long long c)
    {
         long long r=a%c;
         long long k=1;
         while(b)
         {
                 if (b&1)
                   k=(k*r)%c;
                  r=(r*r)%c;
                   b>>=1;
         }
         return k;
    }
    int main()
    {
    	int n;
    	scanf("%d",&n);
    	while(n--)
    	{
    		long a,b,c,count;
    		scanf("%d %d %d",&a,&b,&c);
    		count=fun(a,b,c);
    		printf("%d
    ",count);
    	}
    	return 0;
    }
    

    看着代码很简单,可是背后蕴含了多少了汗水啊!看一下算法吧:其实就是a^29=a^14*a,而a^14=a^7*a^7,a^7=a^3*a^3,a^3=a^2*a,这样求a^29就用了7次乘法,不知你有没有发现,这和二分法查找很相似,每次规模都近视减少了一半。注意long long 的使用,否则就会溢出,得不到正确答案。

    补充:

    利用模运算的运算规则,我们可以使某些计算得到简化。例如,我们想知道3333^5555的末位是什么。很明显不可能直接把3333^5555的结果计算出来,那样太大了。但我们想要确定的是3333^5555(%10),所以问题就简化了。
    根据运算规则(4)a^b% p = ((a % p)^b) % p ,我们知道3333^5555(%10)= 3^5555(%10)。由于3^4 = 81,所以3^4(%10)= 1。
    根据运算规则(3) (a * b) % p = (a % p * b % p) % p ,由于5555 = 4 * 1388 + 3,我们得到3^5555(%10)=(3^(4*1388) * 3^3)(%10)=((3^(4*1388)(%10)* 3^3(%10))(%10)
    =(1 * 7)(%10)= 7。
    计算完毕。
    利用这些规则我们可以有效地计算X^N(% P)。简单的算法是将result初始化为1,然后重复将result乘以X,每次乘法之后应用%运算符(这样使得result的值变小,以免溢出),执行N次相乘后,result就是我们要找的答案。
    这样对于较小的N值来说,实现是合理的,但是当N的值很大时,需要计算很长时间,是不切实际的。下面的结论可以得到一种更好的算法。
    如果N是偶数,那么X^N =(X*X)^[N/2];
    如果N是奇数,那么X^N = X*X^(N-1) = X *(X*X)^[N/2];
    其中[N]是指小于或等于N的最大整数。
    C++实现功能函数:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    /*
    函数功能:利用模运算规则,采用递归方式,计算X^N(% P)
    函数名:PowerMod
    输入值:unsigned int x,底数x
    unsigned int n,指数n
    unsigned int p,模p
    返回值:unsigned int,X^N(% P)的结果
    */
    unsigned PowerMod(unsigned x , unsigned n , unsigned p)
    {
        if (!n)
            return 0;
        unsigned temp = PowerMod((x * x) % p , n >> 1 , p); //递归计算(X*X)^[N/2]
        if (n & 1) //判断n的奇偶性
            temp = (temp * x) % p;
        return temp;
    }
  • 相关阅读:
    ASP.net 知识框架
    MD5验证用户登陆密码
    企业面试题汇总.net
    MD5 加密,AES加密,解密 方法
    我选择了学Python
    校内网的错误信息
    Gmail客户端详细架构之一
    UE
    Gmail客户端详细架构之二:象Gmail一样上传文件
    PATH OR FILE NOT FOUND 之 RTX51.LIB
  • 原文地址:https://www.cnblogs.com/wangyouxuan/p/3270614.html
Copyright © 2011-2022 走看看