背景:
別跟我說這是快速冪,小心我用底數相同的數據卡你。
題目傳送門:
https://www.luogu.org/problem/P1226
題意:
求:nkmodp。
思路:
學習快速冪的請自覺屏蔽。
可能有邊界問題,實際以代碼爲準。
考慮k>⌊n⌋時:
nk=n⌊⌊n⌋n⌋⌊n⌋⋅nk−⌊⌊n⌋n⌋⌊n⌋
我們考慮到⌊⌊n⌋n⌋<=n,k−⌊⌊n⌋n⌋⌊n⌋<⌊n⌋
因此Θ(n)預處理n1,n2,n3,...,n⌊n⌋;n2⌊n⌋,n3⌊n⌋,...,n⌊n⌋⌊n⌋,然後套用上面的式子Θ(1)查詢即可。
這個專門針對喪心病狂的出題人在線卡快速冪。
侷限性:只適用於底數相同或底數較少的冪次方計算。且預處理要Θ(n)。
代碼:
Sqrt要取⌊n⌋+1,防止邊界等問題。
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#define LL long long
using namespace std;
LL n,k,p,Sqrt;
LL block1[10000010],block2[10000010];
void init()
{
block1[0]=1%p;
for(int i=1;i<=Sqrt;i++)
block1[i]=block1[i-1]*n%p;
block2[0]=1%p;
for(int i=1;i<=Sqrt;i++)
block2[i]=block2[i-1]*block1[Sqrt]%p;
}
LL Pow(LL x,LL k)
{
return k<=Sqrt?block1[k]:block2[k/Sqrt]*block1[k-k/Sqrt*Sqrt]%p;
}
int main()
{
scanf("%lld %lld %lld",&n,&k,&p);
Sqrt=sqrt(k)+1;
init();
printf("%lld^%lld mod %lld=%lld",n,k,p,Pow(n,k));
}