zoukankan      html  css  js  c++  java
  • HDU4471 Homework

    题目
    预处理转移矩阵的(2^k)
    然后把关键点按下标排序。
    每次用类似于矩阵快速幂的方法求出两个关键点中间的转移矩阵。

    #include<bits/stdc++.h>
    using namespace std;
    const int N=107,P=1000000007;
    int read(){int x=0,c=getchar();while(!isdigit(c))c=getchar();while(isdigit(c))x=x*10+c-48,c=getchar();return x;}
    int inc(int a,int b){a+=b;return a>=P? a-P:a;}
    int mul(int a,int b){return 1ll*a*b%P;}
    int max(int a,int b){return a>b? a:b;}
    int n,m,q,lim,t,f[N],c[N],C[N];
    struct node{int n,t,c[N];}p[N];
    int operator<(node a,node b){return a.n<b.n;}
    struct mat
    {
        int a[N][N],n,m;
        int*operator[](int x){return a[x];}
        void clear(){memset(a,0,sizeof a);}
        void init(){clear();for(int i=1;i<=n;++i)a[i][i]=1;}
    }A[31],F;
    mat operator*(mat a,mat b)
    {
        mat c;c.clear(),c.n=a.n,c.m=b.m;int i,j,k;
        for(i=1;i<=a.n;++i) for(j=1;j<=b.m;++j) for(k=1;k<=a.m;++k) c[i][j]=inc(c[i][j],mul(a[i][k],b[k][j]));
        return c;
    }
    void init()
    {
        A[0].clear(),F.clear(),A[0].n=A[0].m=F.m=lim,F.n=1;int i,j;
        for(i=1;i<A[0].n;++i) A[0][i][i+1]=1;
        for(i=1;i<=t;++i) A[0][i][1]=c[i-1];
        for(i=1;1<<i<=n;++i) A[i]=A[i-1]*A[i-1];
        for(i=1,j=m;i<=lim&&j;++i,--j) F[1][i]=f[j];
    }
    void power(int k){for(int i=0;i<31;++i)if(k&1<<i)F=F*A[i];}
    int main()
    {
        int T=0,i,j,now,ans;
        while(scanf("%d%d%d",&n,&m,&q)!=EOF)
        {
            for(i=1;i<=m;++i) f[i]=read();
            lim=t=read();
    	for(i=0;i<t;++i) c[i]=read();
            for(i=1;i<=q;++i)
            {
                p[i].n=read(),p[i].t=read();
                if(p[i].n<=n) lim=max(lim,p[i].t);
                for(j=1;j<=p[i].t;++j) p[i].c[j]=read();
            }
    	sort(p+1,p+q+1),init(),now=m;
            for(i=1;i<=q;++i)
            {
                if(p[i].n<=now||p[i].n>n) continue;
                for(j=1;j<=p[i].t;++j) C[j]=p[i].c[j];
                power(p[i].n-now-1),now=p[i].n,ans=0;
                for(j=1;j<=p[i].t;++j) ans=inc(ans,mul(C[j],F[1][j]));
                for(j=lim;j^1;--j) F[1][j]=F[1][j-1];
    	    F[1][1]=ans;
            }
            power(n-now),printf("Case %d: %d
    ",++T,F[1][1]);
        }
    }
    
  • 相关阅读:
    Chapter6 Commodity Forwards
    Chapter5 Prepaid Forwards
    个人作业5——软工个人总结
    软工网络15个人作业3
    软工网络15——结对编程
    软工网络15个人阅读作业2
    软工网络15个人阅读作业1 201521123080曾飞远
    Java课程设计 猜数游戏个人博客
    201521123080《Java程序设计》第14周学习总结
    201521123080《Java程序设计》第13周学习总结
  • 原文地址:https://www.cnblogs.com/cjoierShiina-Mashiro/p/11644556.html
Copyright © 2011-2022 走看看