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 }

 

posted @ 2017-03-23 09:35  SD_le  阅读(230)  评论(0编辑  收藏  举报
重置按钮