Description
Hack 国的居民人人都是 OI 大师,Hometown 得知便赶紧来到 Hack 国学习。可想要进入 Hack 国并不是件容易的事情,首先就必须通过 Hack 国海关小 B 的考验。小 B 觉得 Hometown 比较菜,于是就扔了一道小水题给 Hometown。
给定一个长度为 n 的数列 a i ,接下来会对这个序列进行 m 次操作。操作类型分为以下两种:
• 1 l r,表示将区间 [l,r] 轮转一次,具体来说,a_l ,a_l+1 ,a_l+2 ,··· ,a_r−1 ,a_r 经过一次轮转之后,会变为 a_r ,a_l ,a_l+1 ,··· ,a_r−1 ;
• 2 l r k,询问区间 [l,r] 内 a i = k 的个数。
可惜 Hometown 还是不会做,他只能期待你能解决这个问题了。
对于 100% 的数据,满足 0 ≤ n,m ≤ 10^5 ,1 ≤ a i ≤ n,1 ≤ l i ≤ r i ≤ n。
Solution
一般的数据结构比较难做,怎么办?
可以分块!
对于每一块我们维护一个链表,记录每一块链表的链头和链尾。
查询某个位置现在的标号我们可以先定位到块,然后暴力找。
一个轮转操作相当于将末尾拉出来插到前面去,为了维持块大小恒定,我们还要讲中间的块的末尾移到下一块的头去。
对于每一块开一个桶记录答案。
查询的时候两边的散点就暴力,中间的块就直接在桶里查。
复杂度
接下来讲讲比较不NOIP的做法…
我们先用一个splay维护轮转操作,记好每次操作的左右端点的标号。
轮转很麻烦,我们可以加入一些虚点,不妨将它们权值看成是0,轮转操作就等于将末位置改成0,在头前面修改。
这就变成了单点修改+区间统计答案。
带修主席树??
不需要。
将询问和轮转(因为每次只会变一个值)按照询问的数分类,对于每一类都做一遍,这直接用树状数组维护区间和即可。
复杂度
Code