比赛的时候若是这题过了就进前50
刚开始的时候大家的思路都以为是找规律的题目,于是再推公式,此外还发现类似于杨辉三角。于是又去套杨辉三角的通项去求。
于是TLE了无数次。(每次取范围的最大值也要3s多)。
对于明显的矩阵样子,其实可以转化为矩阵的运算,每一行的转移。就是对一个转移矩阵的幂运算。然后再用快速矩阵幂即可。
A:
10 0 0 1
10 1 0 1
10 1 1 1
0 0 0 1
B:
23
0
0
3
C=A^M *B,ans=C[N]
教训:对于时间限制,即便是最大数据也要秒出才行,不要以为刚刚好够就可以。矩阵的妙用无处不在···~~~~
#pragma comment(linker, "/STACK:1024000000,1024000000") #include<stdio.h> #include<string> typedef __int64 LL; #define INF 10000007 #define MAX 100000 int N,M; LL A[12][12];//init LL B[12];//init LL C[12][12];//ans LL T[12][12];//temp LL D[12][12]; void matrix(LL (*a)[12],LL (*b)[12],LL (*c)[12]) { int i,j,k; LL sum; for(i=0;i<=N+1;i++) { for(j=0;j<=N+1;j++) {sum=0; for(k=0;k<=N+1;k++) sum=sum+(a[i][k]*b[k][j])%INF,sum%=INF; c[i][j]=sum; } } }//刚开始连这个都出错。 void Cal() { //memcpy(C,A,sizeof(A)); int i,j,k; k=M; while(k) { i=k&1; while(i==0) { matrix(A,A,T); memcpy(A,T,sizeof(T)); k>>=1;i=k&1; } matrix(C,A,T); memcpy(C,T,sizeof(T)); matrix(A,A,T);//快速算完后还要再乘一次到下一位,C刚开始设置为单位矩阵 memcpy(A,T,sizeof(T)); k>>=1; } /*for(i=0;i<=N+1;i++) { for(j=0;j<=N+1;j++) printf("%d ",C[i][j]); printf("\n"); }*/ for(i=0;i<=N+1;i++) { LL sum=0; for(j=0;j<=N+1;j++) sum=sum+(C[i][j]*B[j])%INF,sum%=INF; A[0][i]=sum; } printf("%d\n",A[0][N]); } int main() { while(scanf("%d%d",&N,&M)!=EOF) { int i,j; for(i=1;i<=N;i++) scanf("%d",B+i); B[i]=3;B[0]=23; memset(A,0,sizeof(A));memset(C,0,sizeof(C)); for(i=0;i<=N;i++) A[i][0]=10,A[i][N+1]=1,C[i][i]=1;//单位矩阵 C[i][i]=1;A[N+1][N+1]=1; for(i=1;i<N+1;i++) for(j=1;j<=i;j++) A[i][j]=1; /* for(i=0;i<=N+1;i++) { for(j=0;j<=N+1;j++) printf("%d ",A[i][j]); printf("\n"); }*/ Cal(); } return 0; }
2014 ACM/ICPC Asia Regional Xi'an Online 233 Matrix,hdu 5015
原文地址:http://blog.csdn.net/gg_gogoing/article/details/39288385