矩阵快速幂,没啥好说的。。。当时写得还是蛮难看的。
#include<stdio.h>
#include<iostream>
#define LL long long
using namespace std;
LL m;
LL a[2][2];
LL b[30];
LL f1(LL n)
{
LL len=0;
while(n)
{
b[len++]=n%2;
n/=2;
}
return len;
}
void f2(LL len)
{
LL t[2][2]={1,1,1,0},c[2][2];
for(LL i=0;i<len;i++)
{
for(LL j=0;j<2;j++)
for(LL k=0;k<2;k++)
c[j][k]=a[j][k];
if(b[i]!=0)
{
a[0][0]=(t[0][0]*c[0][0]%m + t[0][1]*c[1][0]%m)%m;
a[0][1]=(t[0][0]*c[0][1]%m + t[0][1]*c[1][1]%m)%m;
a[1][0]=(t[1][0]*c[0][0]%m + t[1][1]*c[1][0]%m)%m;
a[1][1]=(t[1][0]*c[0][1]%m + t[1][1]*c[1][1]%m)%m;
}
if(i==len-1) break;
for(LL j=0;j<2;j++)
for(LL k=0;k<2;k++)
c[j][k]=t[j][k];
t[0][0]=(c[0][0]*c[0][0]%m + c[0][1]*c[1][0]%m)%m;
t[0][1]=(c[0][0]*c[0][1]%m + c[0][1]*c[1][1]%m)%m;
t[1][0]=(c[1][0]*c[0][0]%m + c[1][1]*c[1][0]%m)%m;
t[1][1]=(c[1][0]*c[0][1]%m + c[1][1]*c[1][1]%m)%m;
}
printf("%lld\n",a[0][1]);
}
int main()
{
LL n;
while(scanf("%lld%lld",&n,&m)!=EOF)
{
if(n==0) {printf("0\n");continue;}
else
{
LL len=f1(n);
a[0][0]=1,a[0][1]=0,a[1][0]=0;a[1][1]=1;
f2(len);
}
}
return 0;
}