0
点赞
收藏
分享

微信扫一扫

哈尔滨理工大学第12届程序设计竞赛 J 大数乘法

Jonescy 2022-04-04 阅读 65
c++

链接:https://ac.nowcoder.com/acm/contest/30825/J

题目描述
给定整数 x x x, y y y,你需要输出 x y x^y xy mod p p p 的值
输入描述:
第一行一个整数 t t t 1 ≤ t ≤ 10 1 \leq t \leq 10 1t10),表示接下来有 t t t 组测试用例,每个测试用例有三行整数 x , y , p x,y,p x,y,p
0 ≤ x ≤ 100000 0 \leq x \leq 100000 0x100000 0 ≤ y ≤ 1 0 100000 0 \leq y \leq 10^{100000} 0y10100000, 100000 ≤ p ≤ 1000000007 100000 \leq p \leq 1000000007 100000p1000000007
输出描述:
输出 t t t 行,每行一个整数代表 x y x^y xy mod p p p 的值。
示例1
输入

5

3
4
998244353

2
10
998244353

0
100
998244353

1
100
998244353

4
100
1000000007

输出

81
1024
0
1
499445072

备注:
0 0 = 1 0^{0}=1 00=1

思路:

假设 y = 789 y=789 y=789 ,那么
x y   %   p = ( x   %   p ) 700 ∗ ( x   %   p ) 80 ∗ ( x   %   p ) 9 x^y \ \% \ p={(x \ \% \ p)}^{700}*{(x \ \% \ p)}^{80}*{(x \ \% \ p)}^{9} xy % p=(x % p)700(x % p)80(x % p)9

( x   %   p ) 700 = ( x   %   p ) 10 0 7 ( x   %   p ) 80 = ( x   %   p ) 1 0 8 ( x   %   p ) 9 = ( x   %   p ) 1 9 {(x \ \% \ p)}^{700}={(x \ \% \ p)}^{100^7}\\ {(x \ \% \ p)}^{80}={(x \ \% \ p)}^{10^8}\\ {(x \ \% \ p)}^{9}={(x \ \% \ p)}^{1^9}\\ (x % p)700=(x % p)1007(x % p)80=(x % p)108(x % p)9=(x % p)19
于是可以做预处理,先算出 ( x   %   p ) 1 0 n {(x \ \% \ p)}^{10^n} (x % p)10n ,然后与 y y y 的每一位再做幂,把幂的结果做连乘积即可。

AC 代码

#include<bits/stdc++.h>
#define FOR(i,a,b) for(int i=(a);i<=(b);++i)
#define ll long long
using namespace std;

const int maxn=1e6+7;

ll qpow(ll a,ll b,ll p){//a^b%p,快速幂,也可以不用
    ll ans=1,base=a;
    while(b){
        if(b&1) ans*=base,ans%=p;
        base*=base,base%=p;
        b>>=1;
    }
    return ans;
}

signed main(){
	cin.tie(0)->sync_with_stdio(0);
	int T;cin>>T;
	while(T--){
		ll x,p;
		string y;
		vector<ll> pre(maxn,0);
		cin>>x>>y>>p;
		reverse(y.begin(),y.end());
		int len=y.size();
		pre[0]=x%p;
		FOR(i,1,len-1)
			pre[i]=qpow(pre[i-1],10,p);
		ll ans=1;
		FOR(i,0,len-1)
			ans=ans*qpow(pre[i],y[i]-'0',p)%p;
		cout<<ans<<'\n';
	}
	return 0;
}
举报

相关推荐

0 条评论