这鬼家伙已经咕了很久了……数组
SDOIR2的题目挺好玩的~函数
不难发现全部的操做均可以经过区间打Tag实现优化
那么能够维护两个标记$a,b$表示序列中的数为$x$时实际表示的值是$ax+b$。对于一个单点赋值操做把值$x$变为$(x-b)a^{-1}$放进数组里面,对于全局赋值操做直接把数组清空。只清空在上一次清空到这一次清空之间被修改的数组上的位置,那么清空的复杂度必定不会大于前面全部操做的操做次数,复杂度就是对的。spa
至于怎么存这个数组能够离散化也能够像我同样很呆地手写哈希表递归
代码字符串
有一个显然的暴力:设$f_{i,j,k}$表示填满前$i$列、第$i$列两个元素的颜色分别是$j,k$的方案数。复杂度三方一分都没有……get
考虑在这个DP的状态上压掉一维。注意到若是咱们称至少有一个位置有颜色的列是重要列,那么若是咱们能够预处理重要列与重要列之间的转移,咱们就只须要记录最后的重要列上$0$位置处填上的颜色便可,那么DP的复杂度就变成了$O(n^2)$。it
感受很不错,咱们考虑两个重要列之间的可能状态。设$x,y$是其中一个重要列的颜色,考虑另外一个重要列的颜色,有如下几种状况。在下面的叙述中用$?$表示不与$x,y$相同的颜色,一横排的若干个矩阵表示这些矩阵的方案数是相同的。io
$\left(\begin{align*} x && ... && y \ y && ... && x \end{align*}\right)$搜索
$\left(\begin{align*} x && ... && x \ y && ... && y \end{align*}\right)$
$\left(\begin{align*} x && ... && ? \ y && ... && x \end{align*}\right)$ or $\left(\begin{align*} x && ... && y \ y && ... && ? \end{align*}\right)$
$\left(\begin{align*} x && ... && ? \ y && ... && y \end{align*}\right)$ or $\left(\begin{align*} x && ... && x \ y && ... && ? \end{align*}\right)$
$\left(\begin{align*} x && ... && ? \ y && ... && ? \end{align*}\right)$
设$g_{i,0/1/2/3/4}$表示这五种状态中间全为$0$的列数为$i$时的填充方案数,转移枚举最后一个全为$0$的列便可,系数有点复杂,可使用矩阵优化可是我这么无脑的人确定是直接大力写式子啊。
而后去掉头尾的全$0$列(由于它们的方案数能够直接贡献到答案里),咱们就能够每一次枚举两列,用上面求出的$g$数组进行转移了。复杂度$O(n^2)$能够经过96pts。
因此最后的4pts固然是打表啦考虑优化DP。
当你写出式子以后就能够发现:其中的全部操做稍做变换能够变为“快速查询”中的区间加、区间乘、单点修改、单点查询、询问全部的和的操做。写一遍不须要离散化的快速查询配上这个DP就能够了。
须要求一个前缀和一个后缀的最小生成树,咱们能够先预处理好前缀和后缀的生成树,而后考虑链接前缀和后缀之间的边的影响。
若是已经有边链接了前缀和后缀,那么若是再加入一条链接前缀和后缀的边,那么必定要删掉两个经度为$1$的点在前缀最小生成树上的路径的最大边权的边,或者两个经度为$m$的点在后缀最小生成树上的路径的最大边权的边。那么能够发现前缀MST和后缀MST上有用的边只是经度为$1$和$m$的点的虚树上的边。
那么咱们预处理先后缀MST的时候也使用一样的方法,计算完MST以后把两边边界上的点在MST上的虚树记录下来,注意到虚树上一条边的边权能够直接赋为这两个点对应MST路径上的全部边的最大边权,那么一个MST中有效的边的数量就是$O(n)$级别的,每一次合并的复杂度就是$O(nlogn)$。
那么这样作就能够获得一个$O((m+q)nlogn)$的作法。
题设至关于$(p+1)(q+1) \geq n$
考虑以下构造方式:每一次在图中删去度数最小的点和它所连的边直至图为空,设每一次删去的点的序列为$p_1,p_2,...,p_k$,每个点被删去时的度数为$d_1,d_2,...,d_k$,那么周日聚会就邀请$p_1,p_2,...,p_k$,周六聚会就邀请$d_i$取到最大值时对应的图上的全部点。
证实:序列$p$的全部点显然独立,而$d_i$取到最大值时选择的全部点的热闹度就是$\max d_i$。由于$\sum\limits_{i=1}^k (d_i + 1) = n$,$k(\max d_i + 1) \geq \sum\limits_{i=1}^k d_i +1 = n$,因此$(k+1) (\max d_i + 1) \geq n + 1$,因此这样的选择方案是合法的。
删点使用set维护就能够了。
把第$i$个金币和第$i+1$个金币之间的空格个数看做第$m-i$节阶梯的石子数量,那么这个显然是一个阶梯Nim,有效的石子是奇数节的石子,而偶数节的式子对胜负没有影响。
因此咱们只须要考虑奇数节的石子,而对于偶数节的石子直接组合数分配。计算先手获胜的几率彷佛并很差算,可是比较好算的是先手必败的方案数,由于这意味着奇数节阶梯石子异或和为$0$,也就是每一位刚好出现偶数次。发现$n$并非很大,咱们能够直接按位背包。复杂度是$O(mnlogn)$的,可是实际跑得很快。
发现最近的省选很喜欢出思惟的搜索题(隔壁TJOID2T3就是,ZJOID1T1或许也能够算)
以前有一个相似于$0110$缩成$0$、$1001$缩成$1$的方法,可是彷佛很难避免算重,而后发现有一种更优秀的作法……
考虑T.M.序列的一个性质,能够参考OEIS A010060:令初始序列为$0$,而后用$01$代替$0$,$10$代替$1$,作无限次就能够获得T.M.序列。
那么若是一个序列是T.M.序列的子序列,也就必定可以经过$01$填充为$0$、$10$填充为$1$的方式还原为$0$。
那么咱们考虑dfs(s , k)表示当前前缀为s、后面还须要填充k个字符的方案数,转移能够考虑枚举填充的方式:有多是s的$x(2 \not\mid x)$与$x+1$字符组合,也有多是$x(2 \mid x)$与$x+1$字符组合,即在前面加上一个字符使得$s[1]$可以和这个字符组合,被一个单独的字符填充。
不难发现当一个串的长度$>3$时这样的划分方式是惟一的,证实能够不妨假设两种填充的方式都成立,那么若是在第一种填充方式下填充出了前缀$00$或者$11$,那么在第二种填充方式下就会填充出前缀$000$或者$111$,这是不合法的;而若是填充出了$01$或者$10$,那么在第二种填充方式下根本不可能存在合法的字符串知足条件。
而当串长度$\leq 3$时,好比说串$010$,它就能够被填充为$01|01$或者$10|10$,这两种方案都合法,可是这个字符串只能被计数一次,因此这些地方须要特判。
注意到当$|s|=1$时方案数只和$k$的大小有关,在这种状况下咱们能够进入另外一层递归。在这层递归中使用记忆化,那么总的状态数就是$O(logk)$级别的,而solve函数的递归总数是$O(|s|)$级别的,因此复杂度很小能够经过本题。