Gokix

一言(ヒトコト)

关注我

光速幂

U185835 【模板】光速幂

给定底数 \(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;
}
posted @ 2022-05-17 21:22  Gokix  阅读(133)  评论(0编辑  收藏  举报