zoukankan      html  css  js  c++  java
  • Codeforces Round #420 E

     Okabe and El Psy Kongroo

    题意:有n条平行x轴的线段,每条线段的起点为(ai,ci),终点为(bi,ci),且满足ai=b(i-1),从起点出发,每次可以往3个方向走,分别为 (x + 1, y + 1), (x + 1, y), or (x + 1, y - 1),且走的过程必须满足0>=y>=ci,求走到(k,0)有多少种走法

    思路:dp+矩阵快速幂,

    dp[i][0]=dp[i-1][0]+dp[i-1][1]

    ...........

    dp[i][j]=dp[i-1][j]+dp[i-1][j+1]+dp[i-1][j-1]

    ...........

    dp[i][c]=dp[i-1][c]+dp[i-1][c-1]

    得到

    dp[i][0]        dp[i][1]    ... dp[i][j]  ...     dp[i][c]

      s矩阵 [                                                         ]

    dp[i+1][0]   dp[i+1][1] ... dp[i+1][j] ... dp[i+1][c]

    每段线段用一次矩阵快速幂

    AC代码:

    #include "iostream"
    #include "string.h"
    #include "stack"
    #include "queue"
    #include "string"
    #include "vector"
    #include "set"
    #include "map"
    #include "algorithm"
    #include "stdio.h"
    #include "math.h"
    #define ll long long
    #define bug(x) cout<<x<<" "<<"UUUUU"<<endl;
    #define mem(a) memset(a,0,sizeof(a))
    using namespace std;
    const int N=20;
    ll M,Mod=1e9+7;
    struct Mat{
        ll m[N][N];
        Mat(){
            mem(m);
        }
        Mat friend operator* (Mat a, Mat b){
            Mat c;
            for(int i=0; i<M; i++)
                for(int j=0; j<M; j++)
                for(int k=0; k<M; k++)
                    c.m[i][j]=(c.m[i][j]+a.m[i][k]*b.m[k][j])%Mod;
            return c;
        }
    };
    Mat PowMod(Mat a, ll b){
        Mat c;
        for(int i=0; i<M; ++i) c.m[i][i]=1;
        while(b){
            if(b&1) c=c*a;
            a=a*a;
            b>>=1;
        }
        return c;
    }
    ll n,k,a[105],b[105],c[105];
    int main(){
        cin>>n>>k;
        for(int i=0; i<n; ++i){
            cin>>a[i]>>b[i]>>c[i];
        }
        Mat t;
        for(int i=0;i<16;i++)
            for(int j=i-1;j<=i+1;j++)
                if(j>=0&&j<16)
                    t.m[i][j] = 1;
        Mat ans;
        ans.m[0][0]=1;
        for(int i=0; i<n; ++i){
            k-=(b[i]-a[i]);
            M=c[i]+1;
            if(k>=0){
                ans=ans*PowMod(t,b[i]-a[i]);
            }
            else{
                k+=(b[i]-a[i]);
                ans=ans*PowMod(t,k);
            }
        }
        cout<<ans.m[0][0];
        return 0;
    }
    /*
    1 3
    0 3 3
    2 6
    0 3 0
    3 10 2
    */
  • 相关阅读:
    jQuery横向手风琴
    jQuery宽屏游戏焦点图
    手风琴式相册图片展开效果
    鼠标悬停图片分享按钮动画
    jQuery水平滑动菜单
    jQuery图片水平滑动延迟加载动画
    jQuery悬浮焦点图宽屏
    jQuery自定义美化下拉框
    纯CSS3垂直动画菜单
    面向服务与微服务架构
  • 原文地址:https://www.cnblogs.com/max88888888/p/7102892.html
Copyright © 2011-2022 走看看