WC2021T2表达式求值
先放原题:CF878D
每一列中只有$12$种取值,把其排序以后将最终答案拆贡献。
定义$val[i]$为排好序以后的差分数组,那么一列的答案可以表示为:
$$ans=\sum^{i} [ans>=a[i]]*val[i]$$
用一个$dp[mask]=[0,1]$表示当满足对于所有$i \in mask$,$j \notin mask$,有$a[i]>a[j]$时,$dp$值为$1$则表示$ans \in mask$,反之则$ans \notin mask$(即 $ans$ 大于取0的所有元素是否可能),那么$ans$和这个$12$个元素的关系只有$4096$种。
所以我们可以每一行维护一个长度为$4096$的$01$串,如果是取$max$则是取或,取$min$则是取交。
因为每个元素只有$0,1$,所以可以$bitset$优化。
初始第$i$行的$dp[mask]=1$当且仅当$i \in mask$
最后统计答案的时候,对该列元素从小到大枚举,依次把$mask$的每一位从$1$改到$0$,如果$mask$为$1$,则$ans \in mask$,代表$ans>=a[i]$,其中$i$是$\in mask$所有元素中的最小值,那么$ans$加上之前所说的差分数组即可。
复杂度$O(\frac{4096q}{\omega})$
关于本题:
只不过是对于$mask$来统计答案,每一列的贡献独立。
枚举$mask$,然后每行都有一个对应的初始0,1。
对于当前行分别统计到这个状态0,1的个数,然后对于$>,<,?$分别对于四种01搭配组合出新的状态即可。
复杂度$O(1024E)$