码迷,mamicode.com
首页 > 其他好文 > 详细

HDU 4887 Endless Punishment (矩阵离散对数)

时间:2014-08-03 23:24:56      阅读:278      评论:0      收藏:0      [点我收藏+]

标签:style   blog   http   java   art   问题   ar   div   

题意: 给你两个长度为n(n <= 31)的01序列A, B,问A序列最少改变多少次能变成B序列。序列的一次改变是这样的,首先有两个集合S1、S2,每个集合中表示的都是下标,如果集合S1中1的个数是奇数个,那么把序列的第一个数去掉,然后在尾部加上一个数1,偶数个的话则是加上一个数0,然后将S2集合对应的位置异或一下,这就是改变了一次。

思路:由于n<=31,即可知总的不同序列个数是2^n。对于一个序列的一次改变,可以构造个转移矩阵,那么改变一次其实就是乘一次这个矩阵,设初始矩阵是A, 转移矩阵是B, 目标矩阵是C,问题就转换成求A * B^x = C (矩阵里的元素都是mod 2的)。纳尼,这不是就是在求离散对数嘛!只不过是矩阵的离散对数。那么问题就简单了,还是和求普通的离散对数一样。

普通的离散对数 http://blog.csdn.net/jayye1994/article/details/11961635

矩阵离散对数的话,由于总状态数只有2^31,x不会超过总状态数,假设tot是总状态数,定义m = sqrt(tot) + 1,先处理出C * B^i  (0 <= i < m),对于每个i得到的矩阵的状态放入map中,值为i,然后枚举计算 A * B^( i*m ) (1 <= i <= m),一旦得到的状态在map里,说明找到了答案,答案即为 i*m - map(状态),这个想一下就明白的,注意初始和目标状态相同时先特判下,然后注意计算的时候不能整个矩阵相乘,整个矩阵相乘复杂度是O(n^3),由于保存的矩阵只有第一行是有效的,所以复杂度可以转化成O(n^2),这样就不会超时了。



code:


HDU 4887 Endless Punishment (矩阵离散对数),布布扣,bubuko.com

HDU 4887 Endless Punishment (矩阵离散对数)

标签:style   blog   http   java   art   问题   ar   div   

原文地址:http://blog.csdn.net/jayye1994/article/details/38360927

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!