zoukankan      html  css  js  c++  java
  • 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
    ",tmp);
    79     return 0;
    80 }
  • 相关阅读:
    自制操作系统Antz(11)——实现shell(下)命令响应
    自制操作系统Antz(10)——实现shell(上)
    利用Android-FingerprintManager类实现指纹识别
    C语言解析WAV音频文件
    自制病毒——控制桌面鼠标以及开关机
    Linux内核源码分析 day01——内存寻址
    后端必备的Linux知识
    Java基础面试题总结
    自制操作系统Antz(9)——实现内核 (下) 实现图形化界面
    自制操作系统Antz(8)——实现内核 (中) 扩展内核
  • 原文地址:https://www.cnblogs.com/ezyzy/p/6603494.html
Copyright © 2011-2022 走看看