矩阵快速幂,这里的模版就是计算A^n的,A为矩阵。
之前的矩阵快速幂貌似还是个更通用一些。
下面的题目解释来自 我只想做一个努力的人
@@@请注意 ,单位矩阵最初构造 行和列都要是(猫咪数+1)!!!然后按照分析的来,分析中矩阵的下标都是从0开始的。
无法理解的可自行构造案例的矩阵进行验证。
注意一些细节,有些数据要用64位,不然会wa。
//可能是因为原本的模版不适用 #include<stdio.h> #include<string.h> #include<algorithm> using namespace std; int num; struct matrix { long long a[105][105]; }origin,answ; matrix multiply(matrix x,matrix y)//矩阵乘法 { matrix temp; memset(temp.a,0,sizeof(temp.a));//因为后面的代码变了,所以这里也要初始化了 for(int i=0;i<=num;i++) { for(int k=0;k<=num;k++) { if(x.a[i][k])//据说多加这么一句筛选一下就不超时了? { for(int j=0;j<=num;j++) { temp.a[i][j]+=((x.a[i][k]*y.a[k][j])); } } } } return temp; } matrix calc(matrix a,int n)//矩阵快速幂——a^n { if(n==1)return a; matrix e; for(int i=0;i<=num;i++) for(int j=0;j<=num;j++) e.a[i][j]=(i==j); while(n) { if(n&1) e=multiply(e,a); n>>=1; a=multiply(a,a); } return e; } int main() { // freopen("in.txt", "r+", stdin); // freopen("out.txt", "w+", stdout); int n,k,m; char s[5]; while(scanf("%d%d%d",&n,&m,&k)!=EOF) { if(n==0&&m==0&&k==0)break; num=n; for(int i=0;i<=n;i++) for(int j=0;j<=n;j++) origin.a[i][j]=(i==j); while(k--) { long long ii,jj;//这种数据也要64位 scanf("%s",s); if(s[0]=='g') { scanf("%lld",&ii); origin.a[0][ii]++; } else if(s[0]=='s') { scanf("%lld%lld",&ii,&jj); long long kk; for(int iii=0;iii<=n;iii++) { kk=origin.a[iii][ii]; origin.a[iii][ii]=origin.a[iii][jj]; origin.a[iii][jj]=kk; } } else { scanf("%lld",&ii); for(int iii=0;iii<=n;iii++) { origin.a[iii][ii]=0; } } } if(m==0)//之前没考虑到这个? memset(answ.a,0,sizeof(answ.a)); else answ=calc(origin,m); int yi=0; for(int i=1;i<=n;i++) { if(yi) printf(" "); printf("%lld",answ.a[0][i]); yi=1; } puts(""); } return 0; }