光速幂
给定底数 \(x\),模数 \(p\),\(n\) 次询问对于不同的指数 \(a_i\),\(x^{a_i} \bmod p\) 的值。
对于 \(5e6\) 的询问量,一般的 \(O (n\log n)\) 快速幂已经不适用。
这里说一种 \(O(\sqrt{p})\) 预处理,\(O(1)\) 查询的光速幂。
记 \(S=\sqrt{p}+1\),那么 \(x^a=x^{a\bmod S}\times a^{S \times \lfloor \frac{a}{s}\rfloor}\)。
发现前后两个东西都可以 \(O(\sqrt{p})\) 预处理,所以就做完了。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
long long rd(){char ch=getchar();long long x=0,f=1;while(ch<'0' || ch>'9'){if(ch=='-') f=-1;ch=getchar();}while('0'<=ch && ch<='9'){x=x*10+ch-'0';ch=getchar();}return x*f;}
void wr(long long x){if(x<0){putchar('-');x=-x;}if(x>9) wr(x/10);putchar(x%10+'0');}
const long long p=998244352,SP=4e4;
long long t,bs,sp,ksm[SP+10],los[SP+10];
int main(){
long long i,j,u,v;
bs=rd();t=rd();
sp=sqrt(p)+1;
ksm[0]=los[0]=1;
for(i=1;i<=sp;i++)
ksm[i]=ksm[i-1]*bs%p;
for(i=1;i<=sp;i++)
los[i]=los[i-1]*ksm[sp]%p;
while(t--){
u=rd();
wr(ksm[u%sp]*los[u/sp]%p),putchar(' ');
}
putchar('\n');
return 0;
}