T1一看是毒瘤分块根本不想写。
T2部分分都想不到。
T3只会打暴力。
T1
正解是比较有意思的扫描线+线段树维护单调栈。
如果我们把操作序列写出来一定是这个样子的。
(M,AAA,M,AA,MM,A)
然后如果我们把其中的加法操作全部累和就是:
(A_i,M_i,A_j,M_j,A_k,M_k)
这样的话再设(S_i=sumlimits_{j=1}^{i}A_j)。
这样一个新加入的对({A_i,M_i}),能够加入栈中的条件就是:(A_tp+S_i-S_tp<M_i)
那么也就是:
({A_i-S_i})这个序列的上升序列。
可以用线段树维护单调栈维护。
对于某一个位置按操作序列维护出单调栈。
从1到询问时间点的单调栈长度+此时从1到询问时间点的加法标记个数就是值改变的次数。
我们考虑用线段树维护单调栈来做这一过程。
然后再利用扫描线算法。
从左到右,差分询问的区间,线段树上同时支持加入和删除某一个点,区间加和区间求单调栈长度,而同时支持单点修改。
这样对于某一个位置来说,我们先在时间轴上加入所有的覆盖这个点的操作,查询的时候查询时间轴上询问以前的全部区间就可以了。
然后我们可以得到单调栈最后一个元素的大小。
他的大小是(M_i-S_i),这样再用一个树装数组就行了,查询加法操作的前缀和即可。
T2
结论题,不是很能想出来。
T3
网络流。
缩了点之后把反向边开成INF就行了。
这样可以防止从集合(S)向(T)之后再反向流回来。
细节很多。