zoukankan      html  css  js  c++  java
  • 矩阵快速幂 [HNOI2011]数学作业

    问题 G: [HNOI2011]数学作业
    时间限制: 2 Sec 内存限制: 128 MB
    这里写图片描述
    好不容易有一道自己想出来的水题~~
    先说一下怎么构造矩阵吧,
    b: 10^? 1 1
    0 1 1
    0 0 1

    a: 0 0 0
    0 0 0
    1 0 0
    我不证了。。→_→。。自己乘一下试试,我如果这么写,千万别乘反了。。
    下面说说那个10^?, 对于个位数只移一位,而两位数移两位。。只要判断一下你乘到多少位的数就行了,

    #include<cstring>
    #include<cstdlib>
    #include<cstdio>
    #include<iostream>
    #define ll long long
    using namespace std;
    ll n,m,xp[20];
    struct node
    {
        ll f[3][3];
        node(){memset(f,0,sizeof(f));}
    }a,b,ans;
    node operator *(node a,node b)
    {
        node c=node();//
        for(int i=0;i<3;i++)
           for(int j=0;j<3;j++)
              for(int k=0;k<3;k++) 
              {
                 c.f[i][j]=(c.f[i][j]+((a.f[i][k]%m)*(b.f[k][j]%m))%m)%m;
              }
        return c;
    }
    void get(ll x)
    {
        b=node();
        b.f[0][0]=(xp[x]%m)*10;
        b.f[0][1]=b.f[0][2]=b.f[1][1]=b.f[1][2]=b.f[2][2]=1;
    }
    void cheng(ll x)
    {
        while(x)
        {
            if(x&1)ans=b*ans;
            b=b*b;
            x/=2;
        }
    }
    int main()
    {
        scanf("%lld%lld",&n,&m);
        xp[0]=1;
        for(int i=1;i<=19;i++)xp[i]=xp[i-1]*10;
        a.f[2][0]=1;
        for(int i=0;i<3;i++)for(int j=0;j<3;j++)ans.f[i][j]=(i==j);
        for(int i=0;;i++)
        {
            ll k=9*xp[i];
            get(i);
            if(k>=n)break;
            n-=k;
            cheng(k);
    
        }
        cheng(n);
        ans=ans*a;
        printf("%lld",ans.f[0][0]%m);
    }
  • 相关阅读:
    第十一周编程总结
    第十一周助教总结
    第十周编程总结
    第十周学习总结
    第十周助教总结
    第九周学习总结
    第九周编程总结
    第九周助教总结
    第八周学习总结
    第八周编程总结
  • 原文地址:https://www.cnblogs.com/QTY2001/p/7632698.html
Copyright © 2011-2022 走看看