JLOI有意义的字符串
求x=b+d√2mod7528443412579576937
题解
运用特征方程求解,设其通项公式为fn=pSn+qTn,其中S=b+d√2,B为A的共轭式:B=b−d√2,那么将f0,f1代入到通项公式中得到f0=1+q;f1=S+qT=b+d√2+qb−d√2=(1+q)b2+(1−q)d√2;这样的话我们就可以令q=1那么这样的f0=2,f1=b;根据特征方程x2−Ax−B=0,求得A,B的值(其中S,T是该方程的解),解得x1=b,x2=d−b24;那么递推公式就可以求得出来fn=bfn−1+d−b24fn−2,我们要求的解即为Sn=fn−Tn其中1≤Tn≤0
Tn的取值和n的奇偶性有关,偶数则取1;
#include <cstdio>
#include <cmath>
#include <cstring>
#define Rep(i,s,t) for(int i=s;i<=t;i++)
using namespace std;
typedef unsigned long long LL;
const LL MOD=7528443412579576937;
struct Mat {
LL m[2][2];
};
LL b,d,n;
Mat A,I;
LL ksm(LL a,LL b)
{
LL ans=0,p=a;
while(b>0)
{
if(b & 1) ans=(ans+p)%MOD;
p=(p+p)%MOD;
b>>=1;
}
return ans;
}
Mat mul(Mat A,Mat B)
{
Mat c;
memset(c.m,0,sizeof c.m);
Rep(i,0,1) Rep(j,0,1) Rep(k,0,1)
c.m[i][j]=(c.m[i][j]+ksm(A.m[i][k],B.m[k][j]))%MOD;
return c;
}
Mat pow(LL n)
{
Mat ans=A,p=I;n--;
while(n>0)
{
if(n & 1) ans=mul(ans,p);
p=mul(p,p);
n>>=1;
}
return ans;
}
int main()
{
scanf("%llu%llu%llu",&b,&d,&n);
if(n==0) {puts("1");return 0;}
A.m[0][0]=b;A.m[0][1]=2;
I.m[0][0]=b,I.m[1][0]=(d-(b*b))/4;I.m[0][1]=1;
Mat ans=pow(n);
printf("%llu",ans.m[0][0]%MOD-(~n&1));
return 0;
}
鸣谢各大神犇的指导;
于2017.3.1 23:40
PS.一晚上的劳动成果