很高兴的是,看完这个题,我马上想到了是矩阵进行操作,只是苦于敲过的矩阵的题目不是很多,不敢敲
题目中给出的变换都可以用矩阵乘积的形式给出,例如:remove i就是将单位矩阵(i,i)的点置为0;double i就是将单位矩阵中(i,i)点置为2。以此类推。
由于题中的p很大,唯一的办法就是二分求
时刻要记住,在有意义的情况下,矩阵乘法满足结合率,分配率,不满足交换率,矩阵的二分法就是依据这个知识。
通过这个题,我将我手头的那个模板也整理的一下,贴一下代码吧
#include <iostream> #include <string.h> #include <stdio.h> using namespace std; #define N 30 int n,m; struct Matrix { long long matrix[N][N]; //每个元素 long long row,coloumn; //注意这个地方前后要对应 // Matrix(){ // memset(matrix,0,sizeof(matrix)); // } }; Matrix data,matrix[13]; void init(Matrix &a) // 初始化矩阵对象 { memset(a.matrix,0,sizeof(a.matrix)); a.row = n; a.coloumn = n; for(int i = 0;i < n;i++) a.matrix[i][i] = 1; } #define M 10000007 Matrix mutiply(Matrix a,Matrix b) //返回a*b { long long i,j,k; Matrix ans; memset(ans.matrix,0,sizeof(ans.matrix)); ans.row = a.row; ans.coloumn = b.coloumn; for(i=0; i<a.row; i++) for(k=0; k<a.coloumn; k++) if(a.matrix[i][k]) //优化 for(j=0; j<b.coloumn; j++) { ans.matrix[i][j]=(ans.matrix[i][j] + (a.matrix[i][k]*b.matrix[k][j])%M)%M; } return ans; } //(二进制)矩阵快速幂 //调矩阵乘法 Matrix matrix_mi(Matrix p,int k)// (二进制)矩阵快速幂 { Matrix t; init(t); ///注意初始化 //for(int i=0; i<=N; i++) t.matrix[i][i]=1; //t初值为1 初始化;N为数组长度;声明时需初始化,否则其他的值不确定。 while(k) { if(k&1) t=mutiply(t,p); k>>=1; p=mutiply(p,p); } return t; } void deal(int i) { string s; cin >> s; if(s == "remove") { int t; cin >> t;t--; matrix[i].matrix[t][t] = 0; }else if(s == "double") { int t; cin >> t;t--; matrix[i].matrix[t][t] = 2; }else if(s == "add") { int mm,nn; cin >> mm >> nn;mm--;nn--; if(mm == nn) matrix[i].matrix[nn][nn] = 2; else matrix[i].matrix[nn][mm] = 1; }else if(s == "swap") { int mm,nn; cin >> mm >> nn;mm--;nn--; matrix[i].matrix[mm][mm] = 0; matrix[i].matrix[nn][nn] = 0; matrix[i].matrix[mm][nn] = 1; matrix[i].matrix[nn][mm] = 1; }else if(s == "transform") { int c,mm,d,nn; cin >> c >> mm >> d >> nn;mm--;nn--; matrix[i].matrix[mm][mm] = c; matrix[i].matrix[nn][mm] = d; matrix[i].matrix[nn][nn] = 0; }else if(s == "invert") { int mm,nn; cin >> mm >> nn;mm--;nn--; for(int k = mm;k <= nn;k++) matrix[i].matrix[k][k] = 0; for(int k = mm,j = nn;k <= nn;k++,j--) matrix[i].matrix[j][k] = 1; } } int main() { while(cin >> n) { init(data); memset(data.matrix,0,sizeof(data.matrix)); for(int i = 0;i < n;i++) cin >> data.matrix[0][i]; cin >> m; for(int i = 0;i < m;i++) { init(matrix[i]); deal(i); } Matrix re; init(re); //re = mutiply(data,re); for(int i = 0;i < m;i++) { re = mutiply(re,matrix[i]); } int p; cin >> p; int k = p / m; re = matrix_mi(re,k); for(int i = 0;i < p%m;i++) { re = mutiply(re,matrix[i]); } re = mutiply(data,re); for(int i = 0;i < n;i++) { if(i != 0) cout << " "; cout << re.matrix[0][i]; } cout << "\n"; } return 0; }