vijos 1047 送给圣诞夜的礼品 矩阵

题目链接

描述

当小精灵们把贺卡都书写好了之后。礼品准备部的小精灵们已经把所有的礼品都制作好了。可是由于精神消耗的缘故,他们所做的礼品的质量越来越小,也就是说越来越不让圣诞老人很满意。可是这又是没有办法的事情。

于是圣诞老人把礼品准备部的小精灵们聚集起来,说明了自己的看法:“现在你们有n个礼品,其质量也就是降序排列的。那么为了使得这个礼品序列保持平均,不像现在这样很有规律的降序,我这里有一个列表。”
“列表共有m行,这m行都称作操作(不是序列),每一行有n个数字,这些数字互不相同而且每个数字都在1到n之间。一开始,礼品的序列就是现在礼品所处的位置,也就是说,一开始礼品的序列就是1、2、3、4……n;那么然后,我们看列表的第一行操作,设这一行操作的第i个数字为a[i],那么就把原来序列中的第a[i]个礼物放到现在这个序列的第i的位置上,然后组成新的礼物序列。然后,看列表的第二行操作……、第三行操作……一直到最后一行操作,重复上面的操作。当最后一行的操作结束,组成了的序列又按照第一行来操作,然后第二行操作……第三行操作……一直循环下去,直到一共操作了k行为止。最后生成的这个序列就是我们最终礼品送给孩子们的序列了。大家明白了吗?”
“明白了!”
等圣诞老人一个微笑走后,大家却开始忙碌了。因为m值可能很大很大,而小精灵们的操作速度有限。所以可能在圣诞老人去送礼物之前完成不了这个任务。让他们很是恼火……

格式

输入格式

第一行三个数,n,m和k。

接下来m行,每行n个数。

输出格式

一行,一共n个数,表示最终的礼品序列。n个数之间用一个空格隔开,行尾没有空格,需要回车。

输入:

7 5 8
6 1 3 7 5 2 4
3 2 4 5 6 7 1
7 1 3 4 5 2 6
5 6 7 3 1 2 4
2 7 3 4 6 1 5

输出

2 4 6 3 5 1 7

构建矩阵然后快速幂就可以了。

#include <iostream>
#include <vector>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <map>
#include <set>
#include <string>
#include <queue>
#include <stack>
#include <bitset>
using namespace std;
#define pb(x) push_back(x)
#define ll long long
#define mk(x, y) make_pair(x, y)
#define lson l, m, rt<<1
#define mem(a) memset(a, 0, sizeof(a))
#define rson m+1, r, rt<<1|1
#define mem1(a) memset(a, -1, sizeof(a))
#define mem2(a) memset(a, 0x3f, sizeof(a))
#define rep(i, n, a) for(int i = a; i<n; i++)
#define fi first
#define se second
typedef pair<int, int> pll;
const double PI = acos(-1.0);
const double eps = 1e-8;
const int mod = 1e9+7;
const int inf = 1061109567;
const int dir[][2] = { {-1, 0}, {1, 0}, {0, -1}, {0, 1} };
int n, m;
struct Matrix
{
    int a[102][102];
    Matrix() {
        mem(a);
    }
};
Matrix operator * (Matrix a, Matrix b) {
    Matrix c;
    for(int i = 0; i<n; i++) {
        for(int j = 0; j<n; j++) {
            for(int k = 0; k<n; k++) {
                c.a[i][j] += a.a[i][k]*b.a[k][j];
            }
        }
    }
    return c;
}
Matrix operator ^(Matrix a, ll b) {
    Matrix tmp;
    for(int i = 0; i<n; i++)
        tmp.a[i][i] = 1;
    while(b) {
        if(b&1)
            tmp = tmp*a;
        a = a*a;
        b>>=1;
    }
    return tmp;
}
int main()
{
    ll k;
    cin>>n>>m>>k;
    int x;
    Matrix a, ans;
    for(int i = 0; i<n; i++)
        ans.a[i][0] = i+1;
    for(int i = 0; i<n; i++)
        a.a[i][i] = 1;
    Matrix tmp[11];
    for(int i = 0; i<m; i++) {
        for(int j = 0; j<n; j++) {
            scanf("%d", &x);
            tmp[i].a[j][x-1] = 1;
        }
        a = tmp[i]*a;
    }
    int num = k/m;
    a = a^num;
    for(int i = 0; i<k%m; i++)
        a = tmp[i]*a;
    ans = a*ans;
    for(int i = 0; i<n-1; i++)
        cout<<ans.a[i][0]<<" ";
    cout<<ans.a[n-1][0]<<endl;
    return 0;
}
原文地址:https://www.cnblogs.com/yohaha/p/5268008.html