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;
}

 

posted @ 2016-04-30 07:07  哲贤  阅读(292)  评论(0编辑  收藏  举报