数据结构!

lizhous 的博客 / 2023-05-20 / 原文

AT_joisc2014_c 歴史の研究

该起床了。

该起床了。

该起床了。

该起床了。

该起床了。

本题删除会改变最大值,十分麻烦,所以使用回滚莫队即可。

该起床了。

该起床了。

该起床了。

该起床了。

该起床了。

P3245 [HNOI2016]大数

考虑如何提取区间 \([l,r]\) 组成的数。

\(SA_i\) 表示 \(S[i,n]\) 组成的数值,则 \([l,r]\) 组成的数为 \(SU_{l,r}=\frac{SA_l-SA_{r+1}}{10^{n-r}}\) 且统计 \(SU_{l,r}\mod P=0\)

\(10^{n-r}\mod P!=0\) 时:

\[10^{n-r}*\frac{SA_l-SA_{r+1}}{10^{n-r}}\mod P=10^{n-r}*0 \]

\[(SA_l-SA_{r+1})\mod P=0 \]

\[SA_l\mod P=SA_{r+1}\mod P \]

维护 \(SA_i\mod P\) 莫队求区间有多少个相同即可。

\(10^{n-r}\mod P==0\) 时,\(P\in\{2,5\}\)。运用 \(2,5\) 倍数特征即可。

P4688 [Ynoi2016] 掉进兔子洞

不好维护。

发现使用 bitset 可以维护。

bitset 共 \(n\) 位,每个值分配 \(n\),按顺序分布在 bitset 上,每个分配长度等于该值出现的个数。

\([1,2,2,3,3,4]\) 分配为 \([1,2,2,3,3,4]\)\([1,5,1,5,1,5]\) 分配为 \([1,1,1,5,5,5]\)

然后考虑莫队维护。

加入一个数,设当前维护区间共有 \(x\) 个相同的数,该值分配起点为 \(l\),则 bitset 第 \(l+x\) 设为 \(1\)

删除一个数,设不包括当前删除数当前维护区间共有 \(x\) 个相同的数,该值分配起点为 \(l\),则 bitset 第 \(l+x\) 设为 \(0\)

这样做有什么用?

因为我们要删除公共部分,即三个区间每个数出现次数的最小值。这样做若三个区间对应的 bitset 内位置 \(i\) 都为 \(1\),那么这个数是要被删除的。否则该位就会保留。就是一个类似俄罗斯方块的思想。

我们把三个区间对应的 bitset 分别求出来,做按位与,我们就知道有多少个数被删除了。由于是三个区间同时删除,我们还需要把这个数乘三。最后答案就是总区间长度减去删除数个数。

但是你开不下这么大的 bitset。

开不下只是因为莫队离线,所以我们要同时存三倍的bitset。所以我们可以通过减少每次存储个数。

把询问分成若干次经行莫队,每 \(34000\) 次询问跑一遍莫队,求出这 \(34000\) 次的答案。清空掉然后处理下 \(34000\) 次询问。

这样 bitset 只要开 \(34000\) 了,开得下。