P1226
【模板】快速幂||取余运算
快速幂非常的简洁,应用范围也很广,可以做到
代码:
#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<queue>
#include<stack>
#include<cstring>
using namespace std;
long long ans,b,p,k;
int main()
{
cin>>b>>p>>k;
printf("%lld^%lld mod %lld=",b,p,k);
ans = 1;
while(p>0) {
if(p&1)ans=(ans*b)%k;
b=b*b%k;
p>>=1;
}
printf("%lld",ans%k);
return 0;
}
然后是光速幂。
相比于快速幂,它的空间复杂度
这玩意的原理很简单。
我们知道
然后我们只要预处理
换句话说,
更严谨的做法是:
先运用
代码:
#include<iostream>
#include<cstdio>
#define ll long long
using namespace std;
const ll N=5e4;
ll a,b,p;
ll pow[N+5],powb[N+5];
void init() {
pow[0]=powb[0]=1;
for(ll i=1;i<=N;i++) {
pow[i]=pow[i-1]*a%p;
}
for(ll i=1;i<=N;i++) {
powb[i]=powb[i-1]*pow[N]%p;
}
}
inline ll read() {
ll ret=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9') {if(ch=='-') f=-f;ch=getchar();}
while(ch>='0'&&ch<='9') {ret=(ret<<3)+(ret<<1)+ch-'0';ch=getchar();}
return ret*f;
}
void write(ll x) {
if(x<0) {x=-x;putchar('-');}
ll y=10,len=1;
while(y<=x) {y*=10;len++;}
while(len--) {y/=10;putchar(x/y+48);x%=y;}
}
int main() {
a=read();b=read();p=read();
init();
printf("%lld^%lld mod %lld=%lld",a,b,p,powb[b/N]*pow[b%N]%p);
return 0;
}