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.一晚上的劳动成果