【COCI 2012】Rotate

本文探讨如何处理和还原序列在旋转和内部元素旋转操作后的初始状态,涉及旋转序列特性和组内元素顺序变化原理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目大意

要求维护一个序列{An},按照每m个元素为一块分成nm块,其中m|n,有Q个操作,包括以下两种。

  • 将整个序列旋转x
    • 将每一块里面的元素都旋转x

    现在给出序列的最后状态,以及每一步操作,要求还原出最初的状态。

    n,Q<=105


分析

首先先弄清楚一些很重要的东西。
把一个序列左转x位相当于把这个序列右转(lenx)
将一个序列右转x每一个数的位置标号pi=(pi+x)modlen每一个位置对应原序列的编号numi=(numix)modlen
弄懂这个东西非常重要,直接影响了做出这道题需要的时间。
必须举个例子
比如右转x=5位,序列长度len=9
那么原本在第1位的数B跑到了第((1+5)mod9=6)位。
首位对应原来的第(05)mod9=4位。

接下来考虑不同的块之间的同一个位置,把它们称作一个“组”。我们发现无论是第一种操作或者第二种操作,组内元素都是不变的。而第二种操作只会改变组间的顺序(然而环上相对顺序不变),第一种操作也会改变组间顺序,也是环上相对顺序不变,我们不妨开一个变量dgrp表示第一个组的编号来维护组的顺序。

然后第一种操作不仅仅改变了组间顺序,也会改变组内的顺序。至于组内顺序的改变,它也是环上相对顺序不变的。类比第一种操作的维护我们只需要分别给每个组维护一个dx就好了。而我们对d进行修改必定是连续的一段,而对d数组的询问只在最后统计答案时发生,那么只需要维护一个增量数组,最后取前缀和就可以了。


后记

掌握住旋转的特性。
先将模棱两可的式子写好,写对。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值