bzoj 4002: [JLOI2015]有意义的字符串
看到$\frac{b+\sqrt{d}}{2}$就想到$\frac{1+\sqrt{5}}{2}$是$x^2=x+1$的一个解。
于是模仿着这个化简发现它是$x^2=bx+\frac{d-b^2}{4}$的解,这个东西显然是可以矩乘的,然前两项并不是整数。
扒了眼题解,发现有个叫共轭根式的东西,形如$a+\sqrt{b}$和$a-\sqrt{b}$。
于是借助一下$\frac{b-\sqrt{d}}{2}$,显然它也是这个方程的解,而且它加$\frac{b+\sqrt{d}}{2}$是一个整数。
那我们令$f[i]=(\frac{b+\sqrt{d}}{2})^i+(\frac{b-\sqrt{d}}{2})^i=b*f[i-1]+\frac{d-b^2}{4}*f[i-2]$,手算出$f[0]$和$f[1]$。
最后判断一下需不需要-1就行啦。
1 #include<iostream> 2 #include<cstring> 3 #include<algorithm> 4 #include<cstdio> 5 #include<cmath> 6 #define int unsigned long long 7 using namespace std; 8 const int p = 7528443412579576937; 9 int mul(int x,int y) 10 { 11 int lst=0; 12 while(y) 13 { 14 if(y&1)lst=(lst+x)%p; 15 y>>=1; 16 x=(x+x)%p; 17 } 18 return lst; 19 } 20 int b,d,n; 21 struct node 22 { 23 int v[3][3]; 24 int n,m; 25 node() 26 { 27 memset(v,0,sizeof(v)); 28 } 29 friend node operator * (const node &aa,const node &bb) 30 { 31 node c;c.n=aa.n;c.m=bb.m; 32 for(int i=1;i<=aa.m;i++) 33 { 34 for(int j=1;j<=aa.n;j++) 35 { 36 for(int k=1;k<=bb.m;k++) 37 { 38 c.v[j][k]=(c.v[j][k]+mul(aa.v[j][i],bb.v[i][k]))%p; 39 } 40 } 41 } 42 return c; 43 } 44 }chu,ce,now; 45 void pw() 46 { 47 n-=2;now=chu; 48 while(n) 49 { 50 if(n&1)now=now*chu; 51 n>>=1; 52 chu=chu*chu; 53 } 54 return ; 55 } 56 signed main() 57 { 58 scanf("%lld%lld%lld",&b,&d,&n);int t=n; 59 if(n==0) 60 { 61 puts("1");return 0; 62 } 63 if(n==1) 64 { 65 int tmp=(b+sqrt(d))/2; 66 printf("%llu",tmp);return 0; 67 } 68 chu.n=chu.m=2; 69 chu.v[1][2]=1; 70 chu.v[1][1]=b; 71 chu.v[2][1]=(d-b*b)/4; 72 ce.n=1;ce.m=2; 73 ce.v[1][1]=b;ce.v[1][2]=2; 74 pw(); 75 ce=ce*now; 76 int tmp=ce.v[1][1]; 77 if(d!=b*b&&t%2==0)tmp--;tmp=(tmp%p+p)%p; 78 printf("%llu\n",tmp); 79 return 0; 80 }