HDU2035 (with the derivation of properties in number theory and the recursive form of fast modular arithmetic)

Problem Description
Find the integer represented by the last three digits of A^B.
Explanation: A^B means "A raised to the power B"

Input
input data contains multiple test instances, each instance occupies one line, consisting of two positive integers A and B (1<=A, B<=10000). If A=0, B=0, it means that the input data End without processing.

Output
For each test instance, please output the integer represented by the last three digits of A^B. Each output occupies one line.

Sample Input
2 3
12 6
6789 10000
0 0

Sample Output
8
984
1

The following is the multiplication rule for modulo operation
(ab)mod m=[(amodm)(bmodm)] mod m

There are two other
formulas for the modulo operation: Formula ①: ab + 1 a^{b+1}ab+1mod m=[a·( a b a^{b} ab mod m)] mod mab + 1 a^{b+1}
can be obtained by iteration of the formulaab+1mod m=[a·( a b a^{b} abmod m)] mod m=[a·( a·( a b − 1 a^{b-1} ab 1 mod m)mod m )] mod m=...
Solution 1 uses this iterative formula

Proof ①: Let a=km+h, so
ab + 1 a^{b+1}ab+1mod m=[(a mod m)·( a b a^{b} abmod m)]mod m
=[h·( a b a^{b} abmod m)]mod m
=[(km+h)·( a b a^{b} abmod m)]mod m
=[a·( a b a^{b} abmod m)]mod m


Formula ②: aba^{b}abmod m= ( a m o d m ) b (amodm)^{b} (amodm)bmod m

Proof ②: Let a=km+h, so
aba^{b}abmod m= ( k m + h ) b (km+h)^{b} (km+h)bmod m
= h b h^{b} hbmod m= ( a m o d m ) b (amodm)^{b} (amodm)bmod m


Solution 1 uses formula ① (the time complexity is higher than the fast modular operation algorithm)


#include <iostream>
using namespace std;

int main()
{
    
    
    long long base,exponential;//分别代表底数与指数
    while(cin>>base&&cin>>exponential&&base!=0&&exponential!=0){
    
    
        int result=1;
        for(int i=0;i<exponential;i++){
    
    
            result=base*result%1000;//运用了公式①
        }
        cout<<result<<endl;
    }
    return 0;
}


The recursive form of solution 1 is also particularly easy to give

#include <iostream>
using namespace std;

int fastMod(int a,int n)
{
    
    
    if(n==0){
    
    
        return 1;
    }
    else{
    
    
        return (a*(fastMod(a,n-1)))%1000;
    }
}

int main()
{
    
    
    int a,n;
    cin>>a>>n;
    cout<<fastMod(a,n);
    return 0;
}



Solution 2: Fast modular arithmetic.
It is very similar to the code for fast power arithmetic below.

int fastPower(int a,int n)
{
    
    
    int base=a;
    int result=1;
    while(n){
    
    
        if(n&1){
    
    
            result*=base;
        }
        base*=base;
        n>>=1;
    }
    return result;
}

The principle of fast modular operation: express b in binary and reuse the formula (ab) mod m=[(amodm)(bmodm)] mod m to aba^{b}ab mod m to expand.

Example a 5 a^{5}a5 %m fast modular operation solution process

exponential result=(result*base)%m base=(base*base)%m
101 a%m a 2 a^{2} a2%m
10 is 0, the result remains unchanged [( a 2 a^{2} a2%m)*( a 2 a^{2} a2%m)]%m
1 {(a%m)* [( a 2 a^{2} a2%m)*( a 2 a^{2} a2%m) %m]} %m
0
It ends when exponential==0

At this time result=={(a%m)* [( a 2 a^{2}a2%m)*( a 2 a^{2} a2 %m) %m]} %m satisfies the formula obtained by expanding according to the multiplication rule of the modulo operation



The following is the code for this question using fast modular arithmetic

#include <iostream>
using namespace std;
int main() {
    
    
    long long base,exponential;
    //优化:此处为了防止base太大,可根据公式②先对base进行一次取模运算,即base=base%1000;
    while(cin>>base&&cin>>exponential&&base!=0&&exponential!=0) {
    
    
        int result=1;
        while(exponential) {
    
    
            if(exponential&1) {
    
    //指数为奇数时
                result=(result*base)%1000;
            }
            exponential>>=1;//相当于exponential/=2;
            base=(base*base)%1000;
        }
        cout<<result<<endl;
    }
    return 0;
}

Solution 3: The recursive form of fast modular operation
is also very similar to the recursive form code of fast power operation below.

int fastPower(int a,int n)
{
    
    
    if(n==1){
    
    
        return a;
    }
    if(n&1){
    
    
        return a*fastPow(a*a,n/2);
    }
    else{
    
    
        return fastPow(a*a,n/2);
    }
}



It is easy to obtain the recursive form code of fast modular operation by dividing the odd and even by the multiplication operation rule of modular operation.
#include <iostream>
using namespace std;

int fastMod(int a,int n)
{
    
    
    if(n==0){
    
    
        return 1;
    }
    if(n&1){
    
    
        return (((fastMod(a,n/2))*(fastMod(a,n/2)))%1000*(a%1000))%1000;
    }
    else{
    
    
        return ((fastMod(a,n/2))*(fastMod(a,n/2)))%1000;
    }
}

int main()
{
    
    
    int a,n;
    cin>>a>>n;
    cout<<fastMod(a,n);
    return 0;
}

Guess you like

Origin blog.csdn.net/m0_50364811/article/details/117822766