zoukankan      html  css  js  c++  java
  • UVA11653_Buses

    这个题目很有意思,一不小心就会让人坑在里面。

    题意是这样的,给你n,k,l。分别表示总共的长度,长度为5和10的车的不同颜色数量现在问你要把n的填满有多少种方案。

    很多人一开始都会脑子一根筋地想用排列组合去搞这个题目。然而实际上不是这样的。因为排列组合计算量巨大,而且这个题目的数据范围是10^15,绝对无法承受。

    其实我们可以先把n/5,这样相当于是放长度为1和长度为2的方案了。

    我们加入一个状态量f[i],其意义为长度为i的排列方案有多少种?

    那么我们可以迅速地得出这个状态转移的递推式:f[i]=k*f[i-1]+l*f[i-2]。(分别表示放长度为1和2的情况嘛)

    这样你是否有些眼熟了。。。。 对没有错,就是它——矩阵快速幂。

    这样我们要求解的范围十分之小,瞬间变为了log级别,所以答案最终就可以轻松飘过啦。

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #define M 1000000
    #define ll long long
    using namespace std;
    
    struct mat{
        ll a[2][2];
        void init(ll k,ll l)
        {
            a[0][0]=k,a[0][1]=l,a[1][0]=1,a[1][1]=0;
        }
        void E()
        {
            a[0][0]=1,a[1][1]=1,a[0][1]=0,a[1][0]=0;
        }
    }tep,ans;
    
    mat mul(mat a1,mat a2)
    {
        mat f;
        memset(f.a,0,sizeof f.a);
        for (ll i=0; i<2; i++)
            for (ll j=0; j<2; j++)
                for (ll k=0; k<2; k++)
                    f.a[i][j]=(f.a[i][j]+a1.a[i][k]*a2.a[k][j])%M;
        return f;
    }
    
    mat power(mat cur,ll y)
    {
        mat now;
        now.E();
        while (y)
        {
            if (y&1) now=mul(now,cur);
            y>>=1;
            cur=mul(cur,cur);
        }
        return now;
    }
    
    int main()
    {
        ll n,k,l,f1,f2;
        while (scanf("%lld%lld%lld",&n,&k,&l)!=EOF)
        {
            n/=5;
            k%=M,l%=M;
            f1=k,f2=(k*k+l)%M;
            if (n==1)
            {
                printf("%06lld
    ",f1);
                continue;
            }
            if (n==2)
            {
                printf("%06lld
    ",f2);
                continue;
            }
            tep.init(k,l);
            ans=power(tep,n-2);
            printf("%06lld
    ",(ans.a[0][0]*f2+ans.a[0][1]*f1)%M);
        }
        return 0;
    }
    如有转载,请注明出处(http://www.cnblogs.com/lochan)
  • 相关阅读:
    [学习笔记] 网络最大流的HLPP算法
    [学习笔记] LCT 初步
    js中函数的原型及继承
    关于js中函数的一点总结
    关于css实现水平及垂直居中的方法记录
    js基础总结03 --操作数组
    近期学习es6后对变量提升及let和const的一点思考
    用css和js实现侧边菜单栏点击和鼠标滑动特效
    用css或js实现文本输入框的特效
    Jmeter怎样打印日志
  • 原文地址:https://www.cnblogs.com/lochan/p/3426096.html
Copyright © 2011-2022 走看看