uva11551experienced endeavour变换
http://acm.hust.edu.cn/vjudge/contest/view.action?cid=87585#problem/D
题意:第一行输入n和r,n代表n个数,r代表r次变换,第二行输入n个数,再输入n行,每i行第一个数代表第i个数变换时有几个数相加,后面跟数的位置。
思路:用矩阵把变换存起来,由哪些数相加,哪些数的位置上就是1。
#include<iostream> #include<cstring> using namespace std; const int mod=1000; typedef long long ll; struct Matrix { ll v[50][50]; }; Matrix m; ll a[50]; void setup(int n) { for(int l=0;l<n;l++) { cin>>a[l];a[l]%=mod; } memset(m.v,0,sizeof(m.v)); ll x,b; for(int i=0;i<n;i++) { cin>>x; for(int j=0;j<x;j++) { cin>>b; m.v[b][i]=1; } } } void show(Matrix ans,int n) { ll c[50]; for(int i=0;i<n;i++) { c[i]=0; for(int j=0;j<n;j++) { c[i]+=a[j]*ans.v[j][i]; c[i]%=mod; } } for(int k=0;k<n;k++) { cout<<c[k]; if(k<n-1)cout<<" "; } cout<<endl; } Matrix mul(Matrix a,Matrix b,int n) { Matrix c; for(int i=0;i<n;i++) { for(int j=0;j<n;j++) { c.v[i][j]=0; for(int k=0;k<n;k++) { c.v[i][j]+=a.v[i][k]*b.v[k][j]; c.v[i][j]%=mod; } } } return c; } Matrix pow(Matrix a,ll r,int n) { if(r==1)return a; Matrix e=pow(a,r>>1,n); if(r%2)return mul(mul(e,e,n),m,n); else return mul(e,e,n); } int main() { int t,n; ll r; cin>>t; while(t) { cin>>n>>r; setup(n); Matrix ans=pow(m,r,n); show(ans,n); t--; } return 0; }