众所周知,每场比赛都要有一个签到题。
解法
引入
所有可以快速合并的信息均可用线段树维护。
根据某数据结构大师 lxl (hentai) 的理论,值域小,且查询数字种类,可以使用 std::bitset
。
然后这题不就做完了吗。
不知道大家还记不记得第一周留过的一道作业:集合运算 3。
仔细看那道题的操作 $1$ 和操作 $4$,是不是似曾相识?如果不会那道题,可以去 团队文件 找我之前被迫营业写的题解。
正解
建一颗线段树,线段树的每个节点都维护一个 bitset
,查询操作和集合运算那题同理。
区间推平操作:清空相应 bitset
,再将 bitset
中位置 $x$ 赋值为 $1$。
区间加操作:注意到如果是像集合运算那题单纯的左移,会导致有一部分数丢失 (废话,那题要求删除大于值域上界的数),解决方法是将上面本来丢失的部分右移到低位(其实就是循环左移)。
我发现有人理解错循环左移了。循环左移,不是在循环中左移! 循环左移的意思是,你把取模后能得到的 $2024$ 个数想象为一个循环队列,你让循环队列头出队若干次,所有出队的数立刻依次进入循环队列的末尾,相当于只是单纯地移动队头指针。下面给个更严谨的说法,看不懂可以直接跳过。
定义模 $2024$ 的同余类为:
\[\overline{x}=\{2024k + x \vert k \in \mathbb{Z} \}\]记其全体为 $\mathbb{Z}_{2024}$。
$\mathbb{Z}_{2024}$ 与同余类加法形成有限循环群(交换群),生成元为 $\overline{1}$,单位元(幺元)为 $\overline{0}$。
模 $2024$ 的最小非负完全剩余系在商环下形成一个交换环,称为模 $2024$ 剩余类环。
所以你知道啥是循环左移了吧。
现在这题是真的做完了。
时间复杂度 $\mathcal{O}(\lceil \dfrac{2024}{w} \rceil (n + q) \log n)$,其中 $w$ 一般为 $32$ 或 $64$。
代码
什么?还想看代码?不贺难受是吧?