Codeforeces #420 E. Okabe and El Psy Kongroo 递推加矩阵快速幂

来源:互联网 发布:mac加密文件夹弹出 编辑:程序博客网 时间:2024/06/05 08:48

比较好的一道题,首先是是递推,递推很容易想到,我们假设dp[i][j]表示走到i,j的方案数 那么其实就是求出每一段a[i]-b[i]的值 就可以得出来了

可以得到

dp[i][j+1] += dp[i-1][j]; j+1<=ci

dp[i][j-1] += dp[i-1][j];  j-1>=0

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

因为i的范围很大,看了解法后知道要用矩阵快速幂

我们构造一个16*16的矩阵 矩阵mat[i][j] 表示从y轴的i点走到y轴的j点的方案数,当长度为一的时候这个矩阵很好构造 那么长度为2的时候其实就是mat^2,那么直接快速幂求出长度为b[i]-a[i],然后每一段的方案知道后这个题就基本解决了 详细看代码

#include<iostream>#include<cstdio>#include<cmath>#include<algorithm>#include<string>#include<set>#include<map>#include<queue>#include<stack>#include<cstring>using namespace std;#define LL long long#define N 18#define MOD 1000000007llstruct Matrix{    LL dat[N][N];    int n;    Matrix(){        _init();    }    void _init(){        memset(dat,0,sizeof(dat));    }    LL* const operator[](int i)    {return dat[i];    }const LL*  operator[](int i)const{return dat[i];}    void operator%(LL mod)    {        for(int i = 0;i<n;i++)        {            for(int j = 0;j<n;j++)            {                dat[i][j]%=mod;            }        }    }    Matrix operator *(const Matrix& mat){        Matrix temp;        temp.n = mat.n;        for(int i = 0;i<n;i++)        {            for(int j = 0;j<n;j++)            {                for(int k = 0;k<n;k++)                {                   temp[i][j] += dat[i][k]*mat[k][j];                   temp[i][j]%=1000000007ll;                }            }        }        return temp;    }};Matrix ans,sta;void quickPow(LL len){    while(len)    {        if(len&1)        {            ans = ans*sta;            ans%MOD;        }        len >>= 1;        sta = sta*sta;        sta%MOD;    }}int main(){    LL n,k;    while(scanf("%lld%lld",&n,&k)!=EOF)    {        LL a[105],b[105],c[105];        for(int i = 0;i<n;i++)        {            scanf("%lld%lld%lld",&a[i],&b[i],&c[i]);        }        ans._init();        ans.n = 16;        sta.n = 16;        for(int i = 0;i<=ans.n;i++)        {            ans[i][i] = 1;        }        sta._init();        for(int i = 0;i<n;i++)        {            sta._init();            for(int j = 0;j<=c[i];j++)            {                if(j+1<=c[i])                    sta[j][j+1]++;                if(j-1>=0)                    sta[j][j-1]++;                sta[j][j]++;            }            if(b[i]>k)            {                quickPow(k-a[i]);            }            else quickPow(b[i]-a[i]);        }        printf("%lld\n",ans[0][0]);    }return 0;}


阅读全文
0 0
原创粉丝点击