【COCI 2012】Rotate
2015-08-10 16:13
260 查看
题目大意
要求维护一个序列{An}\{ A_n \},按照每mm个元素为一块分成nm\frac{n}{m}块,其中m|nm|n,有QQ个操作,包括以下两种。将整个序列旋转xx位
将每一块里面的元素都旋转xx位
现在给出序列的最后状态,以及每一步操作,要求还原出最初的状态。
n,Q<=105n, Q<=10^5
分析
首先先弄清楚一些很重要的东西。把一个序列左转xx位相当于把这个序列右转(len−x)(len-x)位
将一个序列右转xx位⟺\Longleftrightarrow每一个数的位置标号pi=(pi+x)modlen⟺p_i=(p_i+x)\mod len \Longleftrightarrow每一个位置对应原序列的编号numi=(numi−x)modlennum_i=(num_i-x)\mod len
弄懂这个东西非常重要,直接影响了做出这道题需要的时间。
必须举个例子
比如右转x=5x=5位,序列长度len=9len=9
那么原本在第11位的数BB跑到了第((1+5)mod9=6)((1+5)\mod 9=6)位。
首位对应原来的第(0−5)mod9=4(0-5)\mod 9=4位。
接下来考虑不同的块之间的同一个位置,把它们称作一个“组”。我们发现无论是第一种操作或者第二种操作,组内元素都是不变的。而第二种操作只会改变组间的顺序(然而环上相对顺序不变),第一种操作也会改变组间顺序,也是环上相对顺序不变,我们不妨开一个变量dgrpd_{grp}表示第一个组的编号来维护组的顺序。
然后第一种操作不仅仅改变了组间顺序,也会改变组内的顺序。至于组内顺序的改变,它也是环上相对顺序不变的。类比第一种操作的维护我们只需要分别给每个组维护一个dxd_x就好了。而我们对dd进行修改必定是连续的一段,而对dd数组的询问只在最后统计答案时发生,那么只需要维护一个增量数组,最后取前缀和就可以了。
后记
掌握住旋转的特性。先将模棱两可的式子写好,写对。
相关文章推荐
- Digital Clock 数论水题
- Num 29 : NYOJ : 0071 独木舟上的旅行 [ 贪心 ]
- Linux编程—进程
- HDU 4027 Can you answer these queries? 线段树水题
- Socket 文件传送,加密
- SVN安装配置及安全注意事项
- C# Word控件 文档保护
- NodeJS之Mac初体验
- WPF MVVM模式下实现ListView下拉显示更多内容
- eclipse搭建servlet项目
- 中等难度SQL语句(存储过程,分页,拼接字段、游标,日期类型转换,动态行转列,视图)汇总
- js五种设计模式说明与示例
- linux svn服务配置应用
- Hadoop之谈谈MapReduce
- jquery实现Li滚动时滚动条自动添加样式的方法
- 欢迎使用CSDN-markdown编辑器
- HDOJ-2001-计算两点间的距离
- 快快快!27个提升效率的iOS开源库推荐
- 一种UltraVNC反向连接方式的使用
- Android 手势检测实战 打造支持缩放平移的图片预览效果(上)