链接: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
1≤t≤10),表示接下来有
t
t
t 组测试用例,每个测试用例有三行整数
x
,
y
,
p
x,y,p
x,y,p
0
≤
x
≤
100000
0 \leq x \leq 100000
0≤x≤100000,
0
≤
y
≤
1
0
100000
0 \leq y \leq 10^{100000}
0≤y≤10100000,
100000
≤
p
≤
1000000007
100000 \leq p \leq 1000000007
100000≤p≤1000000007 输出描述: 输出
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){
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;
}
|