数据结构!
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\) 时:
维护 \(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\) 了,开得下。