CF1392G 题解
blog。妈的,第一步就没想到。不过是好题!
肯定是考虑将区间拆成 \(O(1)\) 个前后缀结构去维护。赛时一直在想前缀,发现做不了。。。
但是考虑后缀就是对的,具体就是注意到若同时给 \(S,T\) 进行操作,那么位置数量不变,于是将 \([l,r]\) 拆成 \(S\) 上操作 \([l,n]\) 操作、\(T\) 上操作 \([r+1,n]\) 操作,这样后面的部分就被抵消了,然后就拆成区间了。
后面都比较套路了。记 \(f_i,g_i\) 分别表示 \(S,T\) 操作 \([i,n]\) 操作后形成的字符串状态。这个可以记录每个元素具体跑到了哪里去,\(O(N)\) 直接求出。
此时答案即为
\[k-\min\limits_{1\le l\le r\le n+1,r-l\ge m}\operatorname{popcount}(f_l\oplus g_r)
\]
发现两串的 popcount 恒不变,手玩一下发现答案也可以描述为
\[k-\operatorname{popcount}(S)-\operatorname{popcount}(T)+2\times\max\limits_{1\le l\le r\le n+1,r-l\ge m}\operatorname{popcount}(f_l\cap g_r)
\]
转换视角,枚举 \(st=f_l\cap g_r\),对每个 \(st\) 记录 \(st\subseteq f_l\) 的最小的 \(l\)、\(st\subseteq g_r\) 的最大的 \(r\)。这个可以高维后缀和求出。然后直接 check 每个 \(st\) 是否合法并统计答案即可,这一部分是 \(O(k2^k)\) 的。
总复杂度 \(O(n+k2^k)\)。code