省选模拟6
只会T1,给大家磕头了。
可以根据已知信息得到一个DP方程。
\[f_{i,j}=\max(f_{i-1,j}+[j\le X_i]P_i,f_{i,j-1}+[i\le Y_j]Q_j)
\]
求 \(f_{n,m}\)。
走格子形式 dp 优化可以考虑整行转移
可以写作:
\[f_{i,j}=\max_{k\le j}(f_{i-1,k}+[k\le X_i]P_i+\sum_{t=k+1}^j[i\le Y_t]Q_t)
\]
不妨设 \(lim_{i,j}=[i\le Y_j]Q_j,slim_{i,j}=\sum _{t\le j}lim_{i,t}\)。
有:
\[f_{i,j}=\max_{k\le j}(f_{i-1,k}+[k\le X_i]P_i-slim_{i,k})+slim_{i,j}
\]
设 \(g_{i,j}=f_{i,j}-slim_{i,j}\)
有:
\[g_{i,j}=\max_{k\le j}(g_{i-1,k}+[k\le X_i]P_i+slim_{i-1,k}-slim_{i,k})
\]
注意到所有的 \(slim_{i-1,k}-slim_{i,k}\) 可以总结为 \(O(m)\) 次后缀修改,然而我们做完修改后是做前缀最大值。
考虑将其转化为前缀修改,也就是看作全局加 \(Q_t\),然后看作 \(-[i>Y_t]Q_t\)
那么现在就是一堆前缀加减,操作完后再做前缀 \(\max\)。
发现单次前缀加减后维护前缀 \(\max\) 是容易的,只需要线段树上二分并做区间赋值。
这启发我们研究这些操作,我们将这一堆前缀加减,形如 \((r,w)\) 的二元组按照 \(r\) 从小到大排序。
在执行操作 \((r_i,w_i)\) 后,更新 \([r_{i-1}+1,r_i]\) 的前缀最大值即可。
辅助加入 \((m,0)\)。
这样操作保证了前面操作不影响后续,因此是正确的。
这启发我们前缀修改的性质。