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)$

代码

 

posted @ 2021-02-19 21:57  'Clovers'  阅读(62)  评论(0编辑  收藏  举报