ZOJ Problem Set - 3563 Alice's Sequence II
Chieh
posted @ 2018年3月14日 23:46
in ZOJ
, 311 阅读
飞机票:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=4562
题意很清楚,构造矩阵matrix[][] 其中ai_j表示第i个数字给第j个数字提供了什么。那么就很清楚能写出矩阵,对于m个运算方案,运算k次,则需要运算k/m次全部的+k%m剩下的就是答案,所以这个题想清楚了很简单,直接矩阵快速幂m种方案的矩阵乘积为x,k%m种方案的矩阵乘积为c,初始矩阵为A,则答案矩阵为A*(x)^(k/m)*c,主要是trick!!!!搞死我了,(1)add 运算的话,可能两个值相同,那么对应的点就为2了,(2)transform 可能i和j又相同,这里的话必须执行前面的乘法再置0,如果反过来则错,其余没有什么trick点了,小心点就好了,反正我是被搞死了。//
// main.cpp // zoj3563 // // Created by cfhaiteeh on 14/03/2018. // Copyright © 2018 cfhaiteeh. All rights reserved. // #include <iostream> #include <cstdio> #include <cstring> #include <cmath> #define LL long long using namespace std; const int MOD=10000007; struct Matrix{ LL mat[26][26]; }; int n,m,k; Matrix MUL(Matrix a,Matrix b){ Matrix c; memset(c.mat,0,sizeof(c.mat)); for(int i=1;i<=n;i++){ for(int k=1;k<=n;k++){ if(a.mat[i][k]) for(int j=1;j<=n;j++){ c.mat[i][j]=(c.mat[i][j]+a.mat[i][k]*b.mat[k][j])%MOD; } } } return c; } Matrix poww(Matrix a,int k){ Matrix ans; memset(ans.mat,0,sizeof(ans.mat)); for(int i=1;i<=n;i++)ans.mat[i][i]=1; while(k!=0){ if(k%2==1){ ans=MUL(ans,a); } a=MUL(a,a); k/=2; } return ans; } int ai[26]; int bi[11][26][26]; char ch[123]; void init(){ for(int i=1;i<=n;i++)scanf("%d",&ai[i]); scanf("%d",&m); for(int i=1;i<=m;i++){ for(int j=1;j<=n;j++){ for(int k=1;k<=n;k++){ if(j==k)bi[i][j][k]=1; else bi[i][j][k]=0; } } scanf("%s",ch+1); int u,v,w,x; if(ch[1]=='r'){ scanf("%d",&u); bi[i][u][u]=0; } else if(ch[1]=='d'){ scanf("%d",&u); bi[i][u][u]*=2; } else if(ch[1]=='a'){ scanf("%d%d",&u,&v); bi[i][v][u]++; } else if(ch[1]=='s'){ scanf("%d%d",&u,&v); bi[i][u][u]=0; bi[i][v][v]=0; bi[i][u][v]=1; bi[i][v][u]=1; } else if(ch[1]=='i'){ scanf("%d%d",&u,&v); for(int j=u;j<=v;j++)bi[i][j][j]=0; w=u; for(int j=v;j>=u;j--){ bi[i][j][w]=1; w++; } } else if(ch[1]=='t'){ scanf("%d%d%d%d",&u,&v,&w,&x); bi[i][v][v]=u; bi[i][x][v]=w; bi[i][x][x]=0; } } scanf("%d",&k); } Matrix a,b,c; LL ans[26]; void play(){ int M=k%m; int F=k/m; memset(a.mat,0,sizeof(a.mat)); memset(b.mat,0,sizeof(b.mat)); for(int i=1;i<=n;i++){ a.mat[i][i]=1; } for(int r=1;r<=m;r++){ for(int i=1;i<=n;i++){ for(int j=1;j<=n;j++){ b.mat[i][j]=bi[r][i][j]; }} a=MUL(a, b); if(r==M){ c=a; } } Matrix x=poww(a,F); if(M!=0){ x=MUL(x,c); } memset(ans,0,sizeof(ans)); for(int i=1;i<=n;i++){ for(int j=1;j<=n;j++){ ans[i]=(ans[i]+x.mat[j][i]*ai[j])%MOD; } } } void pri(){ bool fir=1; for(int i=1;i<=n;i++){ if(!fir)printf(" "); fir=0; printf("%lld",ans[i]); } printf("\n"); } int main() { // insert code here... while(scanf("%d",&n)!=EOF){ init(); play(); pri(); } return 0; }