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\n",++T,F[1][1]);
    }
}
posted @ 2019-10-09 21:37  Shiina_Mashiro  阅读(81)  评论(0编辑  收藏  举报