zoukankan      html  css  js  c++  java
  • JLOI2015 有意义的字符串

    Description

     

    Input

    一行三个整数b, d, n。

    Output

    一行一个数表示模7528443412579576937 之后的结果。
     

    Sample Input

    输入1:
    1 5 9
    输入2:
    11 125 6715504

    Sample Output

    输出1:
    76
    输出2:
    1499928102740042526
     

    Data Constraint

     

    好吧。一直没看懂题目名到底有意义在哪= =

    进入正题

    首先我们发现(b+sqrt(d))/2可以是某个方程的解,它符合(-b+sqrt(b*b-4ac))/2a的形式。

    我们发现这个方程是x^2=bx+(d-b^2)/4;

    我们假设一个数列f[n]=((b+sqrt(d))/2)^n;

    由刚才的方程可得f[n]满足f[n]=bf[n-1]+(d-b^2)/4*f[n-2]

    所以对于((b+sqrt(d))/2的n次方我们可以矩乘快速幂求得。

    但实数直接上mod是会挂的!

    我们接着发现方程另外一根为((b-sqrt(d))/2;

    那么它同样满足上面的递推式

    我们设h[n]=((b+sqrt(d))/2)^n+((b+sqrt(d))/2)^n,那么h[n]同样满足递推式,而且h[n]是整数!!!

    又因为((b+sqrt(d)/2)^n绝对值小于1,所以它的影响我们可以直接特判,

    就这样,

    另外,由于mod的数太大,乘法我们要用快速乘实现

    #include<cstdio>
    #include<cstdlib>
    #include<algorithm>
    #include<cmath>
    #include<cstring>
    
    using namespace std;
    typedef long long ll;
    
    struct Matrix{
        ll a[4][4];
        int n,m;
    }dw,dl,y;
    
    ll mo=7528443412579576937ll;
    ll ans,n,b,d;
    
    ll add(ll a,ll b)
    {
        ll lef;
        lef=mo-a;
        if(b<=lef)a=a+b;
        else a=b-lef;
        return a;
    }
    
    ll mul(ll a,ll b)
    {
        ll l;
        l=0;
        while(b){
            if(b%2==1)l=add(l,a);
            a=add(a,a);
            b/=2;
        }
        return l;
    }
    
    Matrix operator *(Matrix a,Matrix b)
    {
        Matrix c;
        int i,j,k;
        memset(c.a,0,sizeof(c.a));
        c.n=a.n;c.m=b.m;
        for(i=1;i<=a.n;i++)
            for(j=1;j<=b.m;j++){
                c.a[i][j]=0;
                for(k=1;k<=a.m;k++)c.a[i][j]=add(c.a[i][j],mul(a.a[i][k],b.a[k][j]));
            }
        return c;
    }
    
    Matrix mi(Matrix x,ll z)
    {
        Matrix l;
        l.n=l.m=2;
        memset(l.a,0,sizeof(l.a));
        l.a[1][1]=1;l.a[2][2]=1;
        while(z){
            if(z%2==1)l=l*x;
            x=x*x;
            z/=2;
        }
        return l;
    }
    
    
    int main()
    {
        scanf("%lld%lld%lld",&b,&d,&n);
        dw.a[1][1]=0;dw.a[1][2]=(d-b*b)/4;
        dw.a[2][1]=1;dw.a[2][2]=b;
        dw.n=dw.m=2;
        dl=mi(dw,n);
        if(n==0)ans=1;
        else{
            ans=mul(dl.a[1][1],2);
            ans=add(ans,mul(b,dl.a[2][1]));
            if(d!=b*b&&n%2==0)ans--;
            if(ans<0)ans+=mo;
        }
        printf("%lld
    ",ans);
    }
  • 相关阅读:
    fatal error C1902: 程序数据库管理器不匹配;请检查安装 (zz)
    c++ std string reserve 测试
    2018年长沙理工大学第十三届程序设计竞赛
    2018年东北农业大学春季校赛
    从本质看海明码——海明码的由来
    CodeForces475
    一维背包问题
    2018年长沙理工大学第十三届程序设计竞赛 箱庭的股市
    高精度加法模板
    for,while,do while
  • 原文地址:https://www.cnblogs.com/applejxt/p/4480501.html
Copyright © 2011-2022 走看看