树形 \(\text{DP}\)。
令 \(f_{u,s,k},(k\in\{0,1\})\) 表示仅考虑以点 \(u\) 为根的子树,固定 \(u\) 的权值为 \(s\),\(u\) 子树中是否有点的权比 \(u\) 的权大的方案数。
\[\begin{aligned}\\ f_{u,s,0}&=\sum_{v\in\operatorname{son}(u)}\sum_{w\in\operatorname{son}(u),w<v}[(\sum_{i=0}^sf_{v,i,0})\times(\sum_{i=0}^sf_{w,i,0})]\\ \end{aligned}\]\[f_{u,s,1}=\sum_{v\in\operatorname{son}(u)}\sum_{w\in\operatorname{son}(u),w<v}[(\sum_{i=s}^mf_{v,i,1}+\sum_{i=s+1}^mf_{v,i,0})\times(\sum_{i=s}^mf_{w,i,1}+\sum_{i=s+1}^mf_{w,i,0})] \]把 \(f_{u,i,k}\) 做个前缀和然后逐个合并,时间复杂度 \(O(nm)\)。
朴素的 \(\text{DP}\) 是令 \(f_{i,j}\) 表示当前数列的和为 \(i\),最后一个数为 \(j\) 的价值和,那么 \(f_{i,j}=c\times f_{i-j,j+1}+f_{i-j,j-1}\)。直接转移,时间和空间复杂度 \(O(n^2)\)。
优化的还没看懂。
我们建一棵以下标为键值的可持久化线段树,维护每个位置的栈顶元素是哪个时刻加入的,然后另维护一棵普通线段树来维护答案,每次区间 push
的时候在可持久化线段树和答案树上分别做一个区间覆盖,同时维护一个 \(Q[t]\) 表示时刻 \(t\) push
进去的元素 \(x\)。
对于单点 pop
,首先在可持久化线段树上查询单点的栈顶的加入时刻 \(t\),然后在 \(t-1\) 时刻的可持久化线段树上查询当时的栈顶加入时刻 \(t'\),\(Q[t']\) 就是 pop
后栈顶的元素。在两棵线段树上分别单点修改即可。
可持久化线段树都要支持区间改值,可以直接用标记永久化。
时间复杂度 \(O(q\log n)\)。