Fast exponentiation-high precision exponentiation

Preface

This article describes the principle and usage of fast power

1. Definition of Fast Exponentiation:

Definition: Quickly find, take base as the base exp to the power, that is, find: base exp ;

Time complexity: O(log₂N)

2. Fast power principle:

Idea: At each step, the exponent is divided into two halves, and the corresponding base is squared. Not only can the very large exponent keep getting smaller, but the number of loops that need to be executed is also smaller, and the final result will never change.

Principle: (a* b)% m = ((a% m) * (b% m))% m

Three, conventional exponentiation:

Code block:

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;

ll Pow1(ll my_base, ll my_exp) {
    
    
	ll ans = 1;
	for (int i = 1; i <= my_exp; i++) ans *= my_base;
	return ans;
}

int main() {
    
    
	ios::sync_with_stdio(false);
	cin.tie(0); //断开同步流 

	ll my_base, my_exp, result;
	clock_t my_start, my_end;

	cin >> my_base >> my_exp;
	my_start = clock();
	//该函数返回值是硬件滴答数
	result = Pow1(my_base, my_exp);
	cout << my_base << "^" << my_exp << "=" << result << endl;
	my_end = clock();
	cout << "time=" << ((double)my_end - my_start) / CLK_TCK << "s" << endl;
	//要换算成秒,需要除以CLK_TCK或者 CLK_TCKCLOCKS_PER_SEC

	return 0;
}

operation result:
Insert picture description here

Four, simple and fast exponentiation:

Code block:

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;

ll Pow2(ll x, ll y) {
    
    
	ll ans = 1, base = x;
	while (y != 0) {
    
    
		if (y % 2 != 0) ans *= base;
		base *= base;
		y /= 2;
	}
	return ans;
}

int main() {
    
    
	ios::sync_with_stdio(false);
	cin.tie(0); //断开同步流 

	ll my_base, my_exp, result;
	clock_t my_start, my_end;

	cin >> my_base >> my_exp;
	my_start = clock();
	//该函数返回值是硬件滴答数
	result = Pow2(my_base, my_exp);
	cout << my_base << "^" << my_exp << "=" << result << endl;
	my_end = clock();
	cout << "time=" << ((double)my_end - my_start) / CLK_TCK << "s" << endl;
	//要换算成秒,需要除以CLK_TCK或者 CLK_TCKCLOCKS_PER_SEC

	return 0;
}

operation result:
Insert picture description here

Four, recursive fast exponentiation:

Code block:

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;

ll Pow3(ll my_base, ll my_exp) {
    
    
	if (my_exp == 1)return my_base;
	ll ans = Pow3(my_base, my_exp / 2);
	return (my_exp % 2 == 0 ? 1 : my_base) * ans * ans;

}

int main() {
    
    
	ios::sync_with_stdio(false);
	cin.tie(0); //断开同步流 

	ll my_base, my_exp, result;
	clock_t my_start, my_end;

	cin >> my_base >> my_exp;
	my_start = clock();
	//该函数返回值是硬件滴答数
	result = Pow3(my_base, my_exp);
	cout << my_base << "^" << my_exp << "=" << result << endl;
	my_end = clock();
	cout << "time=" << ((double)my_end - my_start) / CLK_TCK << "s" << endl;
	//要换算成秒,需要除以CLK_TCK或者 CLK_TCKCLOCKS_PER_SEC

	return 0;
}

operation result:
Insert picture description here

V. Quick exponentiation by bit arithmetic:

Code block:

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;

ll Pow3(ll my_base, ll my_exp) {
    
    
	int ans = 1, base = my_base;
	while (my_exp != 0) {
    
    
		if (my_exp & 1 != 0)
		{
    
    
			//逐位获取b的二进制位,遇0累乘
			ans *= base;
		}
		base *= base;
		my_exp >>= 1;
	}
	return ans;
}

int main() {
    
    
	ios::sync_with_stdio(false);
	cin.tie(0); //断开同步流 

	ll my_base, my_exp, result;
	clock_t my_start, my_end;

	cin >> my_base >> my_exp;
	my_start = clock();
	//该函数返回值是硬件滴答数
	result = Pow3(my_base, my_exp);
	cout << my_base << "^" << my_exp << "=" << result << endl;
	my_end = clock();
	cout << "time=" << ((double)my_end - my_start) / CLK_TCK << "s" << endl;
	//要换算成秒,需要除以CLK_TCK或者 CLK_TCKCLOCKS_PER_SEC

	return 0;
}

operation result:
Insert picture description here

Six, high-precision fast exponentiation:

Code block:

#include <bits/stdc++.h>
using namespace std;

typedef long long ll;
const ll mod = 1e7;   //自定义取模的数据,视数据大小的情况而定

//a ^ b
ll ksm(ll a, ll b, ll mod) {
    
        //time_complex=O(logn)
	ll ans = 1, base = a;
	while (b != 0) {
    
    
		if ((b & 1) != 0) {
    
       //“b & 1”指取b的二进制数的最末位
			ans = (ans * base) % mod;   //累乘,以便随时对ans做出贡献。
		}
		base = (base * base) % mod;
		b >>= 1;    //右移1位,删去最低位。
	}
	return ans;
}

int main() {
    
    
	ios::sync_with_stdio(false);
	cin.tie(0); //断开同步流 

	ll a, b, result;
	clock_t my_start, my_end;

	cin >> a >> b;
	my_start = clock();
	//该函数返回值是硬件滴答数
	result = ksm(a, b, mod); 
	cout << a << "^" << b << "=" << result << endl;
	my_end = clock();
	cout << "time=" << ((double)my_end - my_start) / CLK_TCK << "s" << endl;
	//要换算成秒,需要除以CLK_TCK或者 CLK_TCKCLOCKS_PER_SEC

	return 0;
}

operation result:
Insert picture description here

Six, python high-precision fast exponentiation:

Code block:

a, b = map(int, input().split())
mod = 10000000
result = pow(a, b, mod)
print("{0}^{1}={2}".format(a, b, result))

operation result:
Insert picture description here

7. Actual combat exercises:

Source of subject:
https://ac.nowcoder.com/acm/problem/213988
Insert picture description here
Insert picture description here

Program code: The
first way of writing:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
/*long long qmod(ll a,ll b,int c)
{
    if(b==1) return a;
    if(b&1) return a*qmod(a,b-1,c)%c;
    else
    {
        ll m=qmod(a,b/2,c);
        return m*m%c;
    }
    
} *///用二分还是超时
ll qmod(ll a,ll b,ll c)//快速幂
{
    
    
    int r=1;
    while(b)
    {
    
    
        if(b&1) r=a*r%c;
        a=a*a%c;
        b>>=1; //b的二进制形式删除最后一位
    }
    return r;
}
int main()
{
    
    
    long long a,b,c;
    c=998244353;
    cin>>a>>b;
    if(a>c) a=a%c;
    else
    {
    
    
        ll ans=qmod(b+1,a,c);
        cout<<ans<<endl;
    }
    
    
}

The second way of writing:

n, m = map(int, input().split())
sum = pow(m+1,n,998244353)
print(sum)

operation result:
Insert picture description here

to sum up

This article describes the basic usage of fast power.

If there are errors, please advise!

Guess you like

Origin blog.csdn.net/ivan_9/article/details/113443451