题解:P15921 [TOPC 2023] Exponentiation
题解:P15921 [TOPC 2023] Exponentiation
思路
我们记 化身拉玛努金,考虑如下式子。
由题目我们可以知道
也就是
因为答案实在过大,记得开 __uint128_t,将矩阵中的负数改成与其同余的一个正数。
AC Code
::::success[Code]
#include<bits/stdc++.h>
using namespace std;
#define int __uint128_t
inline int read(){
int x=0,y=0;char c=0;
while(!isdigit(c))y|=c=='-',c=getchar();
while(isdigit(c))x=(x<<3)+(x<<1)+(c^48),c=getchar();
return y?-x:x;
}
inline void write(int x){
if(x>9) write(x / 10);
putchar(x % 10 + '0');
}
int n,k,mod;
struct matrix{
int a[50][50],r,l;
matrix(){
l=0,r=0;
memset(a,0,sizeof(a));
}
void build(){
for(int i=1;i<=r;i++)a[i][i]=1;
}
matrix mul(matrix x){
matrix y;
y.r=r;
y.l=x.l;
for(int i=1;i<=r;i++){
for(int j=1;j<=x.l;j++){
for(int k=1;k<=l;k++){
y.a[i][j]+=a[i][k]*x.a[k][j];
y.a[i][j]=(y.a[i][j]%mod+mod)%mod;
}
}
}
return y;
}
}p,q;
matrix qpow(matrix a,int b){
matrix ans;
ans.l=2,ans.r=2;
ans.build();
while(b){
if(b&1)ans=ans.mul(a);
a=a.mul(a);
b=b>>1;
}
return ans;
}
signed main(){
k=read(),n=read(),mod=read();
if(n==0){
cout<<2;
return 0;
}
p.r=p.l=q.r=2;
q.l=1;
p.a[1][1]=k;p.a[1][2]=mod-1;p.a[2][1]=1;
q.a[1][1]=k;q.a[2][1]=2;
p=qpow(p,n-1);
p=p.mul(q);
write(p.a[1][1]);
return 0;
}
::::