https://vijos.org/p/1049

P1049送给圣诞夜的礼品

 
Pascal
  • Pascal
  • C
  • C++
  • Python 2.x
  • Java

取消 | 清空代码

 

描述

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

于是圣诞老人把礼品准备部的小精灵们聚集起来,说明了自己的看法:“现在你们有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个数之间用一个空格隔开,行尾没有空格,需要回车。

样例1

样例输入1[复制]

 
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

样例输出1[复制]

 
2 4 6 3 5 1 7

题意:初始数列为1.2.3...n;然后给了m个操作,每个操作都有n个数,表示把第a[i]的数放到第i位置上了,题目让求经过k次操作后的数列
分析:后的序列。m<=10, k<2^31。
    首先将这m个置换“合并”起来(算出这m个置换的乘积),然后接下来我们需要执行这个置换k/m次(取整,若有余数则剩下几步模拟即可)。注意任意一个置换都可以表示成矩阵的形式。例如,将1 2 3 4置换为3 1 2 4,相当于下面的矩阵乘法:
(第i行第a[i] 为1;因为要把第a[i]个数放到第i个位置)
     
    置换k/m次就相当于在前面乘以k/m个这样的矩阵。我们可以二分计算出该矩阵的k/m次方,再乘以初始序列即可。做出来了别忙着高兴,得意之时就是你灭亡之日,别忘了最后可能还有几个置换需要模拟。
 #include <iostream>
#include <cstring>
#include <algorithm>
#include <cstdio>
using namespace std;
struct Mat
{
int mat[][];
};
Mat p[];
int n,m,k;
Mat operator * (Mat x, Mat y)
{
Mat c;
memset(c.mat, , sizeof(c.mat));
for(int t = ; t <= n; t++)
{
for(int i = ; i <= n; i++)
{
for(int j = ; j <= n; j++)
c.mat[i][j] += x.mat[i][t] * y.mat[t][j];
}
}
return c;
}
Mat operator ^ (Mat x, int t)
{
Mat c;
for(int i = ; i <= n; i++)
for(int j = ; j <= n; j++)
c.mat[i][j] = (i == j);
while(t)
{
if(t & )
c = c * x;
x = x * x;
t >>= ;
}
return c;
}
int main()
{
while(scanf("%d%d%d", &n,&m,&k) != EOF)
{
Mat res,c,a;
for(int i = ; i <= n; i++)
a.mat[i][] = i; for(int i = ; i <= n; i++)
for(int j = ; j <= n; j++)
res.mat[i][j] = (i == j); for(int i = ; i <= m; i++)
{
memset(c.mat, , sizeof(c.mat));
for(int j = ; j <= n; j++)
{
scanf("%d", &p[i].mat[j][]);
c.mat[j][ p[i].mat[j][] ] = ;
}
res = c * res;
} res = res ^ (k / m);
a = res * a;
int temp = k % m;
for(int i = ; i <= temp; i++)
{
memset(c.mat, , sizeof(c.mat));
for(int j = ; j <= n; j++)
c.mat[j][ p[i].mat[j][] ] = ;
a = c * a;
}
for(int i = ; i < n; i++)
{
printf("%d ",a.mat[i][]);
}
printf("%d\n",a.mat[n][]); }
return ;
}

P1049送给圣诞夜的礼品(矩阵十大问题之四)的更多相关文章

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

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

  2. ( VIJOS )VOJ 1049 送给圣诞夜的礼品 矩阵快速幂

    https://vijos.org/p/1049   非常普通的矩阵快速幂... 但是我 第一次写忘了矩阵不能交换律... 第一二次提交RE直到看到题解才发现这道题不能用递归快速幂... 第三次提交成 ...

  3. vijosP1049 送给圣诞夜的礼品

    vijosP1049 送给圣诞夜的礼品 链接:https://vijos.org/p/1049 [思路] 快速幂+矩阵转换. 将m次矩阵的转换看作是一次快速幂中的乘法操作,这样可以用O(log(k/m ...

  4. VOJ1049 送给圣诞夜的礼品 【矩阵经典4】

    任意门:https://vijos.org/p/1049 描述 当小精灵们把贺卡都书写好了之后.礼品准备部的小精灵们已经把所有的礼品都制作好了.可是由于精神消耗的缘故,他们所做的礼品的质量越来越小,也 ...

  5. 矩阵经典题目四:送给圣诞夜的礼品(使用m个置换实现对序列的转变)

    https://vijos.org/p/1049 给出一个序列,含n个数.然后是m个置换,求对初始序列依次进行k次置换,求最后的序列. 先看一个置换.把置换表示成矩阵的形式.然后将m个置换乘起来.那么 ...

  6. 【vijos1049】送给圣诞夜的礼品

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

  7. vijos1049送给圣诞夜的礼品

    这题犯了两个sb错误,写下来,为以后做个警告 一.mul过程中将k作为了循环变量 二.看错了题…… 题目中说是数到k行,而我却以为数k遍…… 做矩阵乘法,只要记住一句话:置换一定可以写成矩阵的形式! ...

  8. VOJ 1049送给圣诞夜的礼物——矩阵快速幂模板

    题意 顺次给出 $m$个置换,反复使用这 $m$ 个置换对一个长为 $n$ 初始序列进行操作,问 $k$ 次置换后的序列.$m<=10, k<2^31$. 题目链接 分析 对序列的置换可表 ...

  9. Codevs 1293 送给圣诞夜的极光

    1293 送给圣诞夜的极光  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 黄金 Gold 题解  查看运行结果     题目描述 Description 圣诞老人回到了北极圣 ...

随机推荐

  1. 两种方式判断类的存在→className getAttribute

    通过className获取 var p = document.getElementsByTagName('p'); for(var i = 0;i <p.length;i++){ if(p[i] ...

  2. Netty解决TCP粘包/拆包问题 - 按行分隔字符串解码器

    服务端 package org.zln.netty.five.timer; import io.netty.bootstrap.ServerBootstrap; import io.netty.cha ...

  3. 【转】【WPF】WriteableBitmap应用及图片数据格式转换

    使用 WriteableBitmap 类基于每个框架来更新和呈现位图.这对于生成算法内容(如分形图像)和数据可视化(如音乐可视化工具)很有用. WriteableBitmap 类使用两个缓冲区.“后台 ...

  4. 【Android性能优化】(一)使用SparseIntArray替换HashMap

    SparseArray是android里为<Interger,Object>这样的Hashmap而专门写的class,目的是提高效率,其核心是折半查找函数(binarySearch)

  5. 加密算法使用(四):AES的使用

    AES是一种对称加密方式,比DES更为安全,用一个秘钥加密数据之后,可以用同一个秘钥对加密后的数据解密还原,以下是一套以字符串为例子的使用全过程演示, 用到了 commons-codec.jar pa ...

  6. ASP.NET中进行消息处理(MSMQ) 一

    MSMQ是微软消息队列的英文缩写.那么什么是消息队列?这些介绍网上一大片这里就不多说了.本文对于大虾级的人物来说这只是小玩意而已,对于初学者来说这文章还是有一定的帮助,希望路过的大虾们别笑话我班门弄斧 ...

  7. C语言学习的记忆

    优于他人的技能 会玩双截棍: 我的经验就是Practice make perfect,熟能生巧:还有就是坚持不懈. 关于C语言的学习的回忆 1.我通过老师的教导和课外C语言书籍中学习,和我的技能相比, ...

  8. WIN8 浏览器排版不兼容问题

    经常访问网站失败 访问部分网站只显示白底蓝字没有排版也没有图片 尝试了网上的各种方法,也是用了360和百度安全管家的网页修复 重置了IE设置 都不行!!! 最后有效的方法是 更换DNS 208.67. ...

  9. MVVM开源框架Knot.js 教程1 - CBS初步

    Knotjs教程系列 1.CBS初步(本文) 2.Knot.js Debugger ....持续增加中 CBS初步 学习Knot.js,实际上就是学习如何使用CBS.CBS使用和CSS类似的原理,将绑 ...

  10. Java并发编程-CAS

    CAS(Compare and swap)比较和替换是设计并发算法时用到的一种技术.简单来说,比较和替换是使用一个期望值和一个变量的当前值进行比较,如果当前变量的值与我们期望的值相等,就使用一个新值替 ...