• 福州大学oj 1752 A^B mod C ===>数论的基本功。位运用。五星*****


    Problem 1752 A^B mod C

    Accept: 579    Submit: 2598
    Time Limit: 1000 mSec    Memory Limit : 32768 KB

    Problem Description

    Given A,B,C, You should quickly calculate the result of A^B mod C. (1<=A,B,C<2^63).

    Input

    There are multiply testcases. Each testcase, there is one line contains three integers A, B and C, separated by a single space.

    Output

    For each testcase, output an integer, denotes the result of A^B mod C.

    Sample Input

    3 2 4 2 10 1000

    Sample Output

    1 24

    Source

    FZU 2009 Summer Training IV--Number Theory
    很多题目,平时提交是对的。但是比赛的时候,数据加强,数字范围变化就错了。
    溢出......
     
    这个题,两个知识点,很好的题目。
    1. a^b%m;
    2. a*b%m;
    由于这道题,数字的大小是(1<=A,B,C<2^63).
    一开始,我们都会想到用__int64 或者 long long
    计算的方法也有多种,但是本质上是一样的。
    整数的二进制拆分。
    在计算的过程中会出现一些问题。
    错误的代码:
     
     1  Source Code
     2 RunID: 508246UserID: 987690183Submit time: 2013-08-12 18:14:52Language: Visual C++Length: 497 Bytes.Result: Wrong Answer
     3 
     4 #include<iostream>
     5 #include<cstdio>
     6 #include<cstdlib>
     7 #include<cstring>
     8 using namespace std;
     9 
    10 
    11 
    12 unsigned __int64  mgml(unsigned __int64 a,unsigned __int64 n,unsigned __int64 m )
    13 {
    14     unsigned __int64 ans=1;
    15     a=a%m;
    16     while(n)
    17     {
    18         if(n&1)
    19         {
    20             ans=(ans*a)%m;//当数字很大的时候,ans*a就溢出了。
    21         }
    22         n=n>>1;
    23         a=(a*a)%m;//这边的也是一样的。
    24     }
    25     return ans;
    26 }
    27 
    28 int main()
    29 {
    30     unsigned __int64 a,b,c;
    31     while(scanf("%I64u%I64u%I64u",&a,&b,&c)>0)
    32     {
    33         printf("%I64u
    ",mgml(a,b,c));
    34     }
    35     return 0;
    36 }


    因此,通过以前的方法就难以解决这个问题,这也是这道题好的地方了。

    处理的方法,加一个a*b%m的函数,解决在错误代码里遇到的问题。

    AC代码:

     1 #include<iostream>
     2 #include<stdio.h>
     3 #include<cstring>
     4 #include<cstdlib>
     5 using namespace std;
     6 
     7 typedef __int64 LL;
     8 
     9 LL pow1_sum(LL a,LL b,LL mod)
    10 {
    11     a=a%mod;
    12     b=b%mod;
    13     LL cur=0;
    14     while(b)
    15     {
    16         if(b&1)
    17         {
    18             cur=cur+a;
    19             if(cur>=mod) cur=cur-mod;
    20         }
    21         a=a<<1;
    22         if(a>=mod) a=a-mod;
    23         b=b>>1;
    24     }
    25     return cur;
    26 }
    27 LL pow_sum(LL a,LL b,LL mod) //a^b%mod
    28 {
    29     LL cur= 1;
    30     a=a%mod;
    31     while(b)
    32     {
    33         if(b&1)
    34         {
    35             cur=pow1_sum(cur,a,mod);
    36         }
    37         a=pow1_sum(a,a,mod);
    38         b=b>>1;
    39     }
    40     return cur;
    41 }
    42 void solve(LL a,LL b,LL mod)
    43 {
    44     LL result = pow_sum(a,b,mod);
    45     printf("%I64d
    ",result);
    46 }
    47 int main()
    48 {
    49     LL a,b,mod;
    50     while(scanf("%I64d%I64d%I64d",&a,&b,&mod)>0)
    51     {
    52         solve(a,b,mod);
    53     }
    54     return 0;
    55 }


    这道题,没有很复杂的算法,但是又容易出错,很值得推荐

  • 相关阅读:
    android部分控件应用解析
    CodeForces Round #179 (295A)
    面试题27:连续子数组的最大和
    java写文件时,输出不完整的原因以及解决方法
    序列化和反序列化--转
    Java多线程编程那些事:volatile解惑--转
    转变--一个平凡人的2017年总结及2018年展望
    系列文章--批处理学习
    set命令
    bat计算两个时间差
  • 原文地址:https://www.cnblogs.com/tom987690183/p/3253598.html
Copyright © 2020-2023  润新知