快速幂的多次查找,LibreOJ - 162
题目描述
这可能也是一道模板题。
给出正整数x和n个正整数ai ,求 (x^ai)mod p。
输入格式
第一行,两个正整数 x,n。
第二行, n个正整数ai 。
输出格式
一行n个正整数,分别表示 (x^ai)mod p。
样例
输入
2 3
1 2 3
输出
2 4 8
数据范围与提示
对于100%的数据,1<= n <= 5 * 10^6,1<= x, ai < p,p = 998244352
题解
令
\[S=p^{\frac{1}{2}}+1
\]
则
\[x^a=x^{amodS}*x^{\left \lfloor \frac{a}{S} \right \rfloor*S}
\]
将a次方拆成两部分,分别算并保存在数组里,查找时直接调即可。
两部分的数组长短与S有关,两数组长短互相制约,取$$S=p^{\frac{1}{2}}+1$$ 较为合适。
代码
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod=998244352;
const int S=31596;//S = 1 + sqrt(mod)
ll a[32000],b[32000];
int main()
{
ll x; int n; scanf("%lld%d",&x,&n);
a[0]=1,b[0]=1;
for(int i=1;i<=S;i++)
a[i]=a[i-1]*x%mod;
for(int i=1;i<=S;i++)
b[i]=b[i-1]*a[S]%mod;
for(int i=1;i<=n;i++){
ll aa; scanf("%lld",&aa);
printf("%lld ",a[aa%S]*b[aa/S]%mod);
}
}