Codeforces 1149 题解

A

特判全是 \(2\),对于有 \(1\) 的情况把 \(1\) 放到第二个和最后。
时间复杂度 \(O(n)\).
代码: 76492031

B

考虑只有一次询问的情况,有一个 \(O(n^3)\) 的 DP,设 \(f[i][j][k]\) 表示三个串分别匹配到 \(i,j,k\),大串最短匹配到哪。转移形如 \((i,j,k)\rightarrow (i+1,j,k),(i,j+1,k),(i,j,k+1)\).
有修改相当于给某一维 \(+1\)\(-1\),显然影响到的 \((i,j,k)\) 只有 \(O(L^2)\) 个,直接改即可。(\(L\)\(A,B,C\) 串长度)
时间复杂度 \(O(n|\Sigma|+qL^2)\).
代码: 76579067

C

显然问题就相当于选择三个数 \(i,j,k\) 满足 \(0\le i\le j\le k\le n\),最大化 \(s_i-2s_j+s_k\) (\(s\) 为前缀和),修改的形式为区间加或减 \(2\).
线段树经典题。直接线段树维护 \(s_i\), \(-s_j\), \(s_i-2s_j\), \(-2s_j+s_k\), \(s_i-2s_j+s_k\)\(\max\) 即可。
时间复杂度 \(O(n+q\log n)\).
代码: 76672305

D

由于边权只有两种,我们需要考察的状态显然是仅加入 \(a\) 边之后的连通状态。
考虑一条从 \(1\)\(p\) 的路径,为了满足最小生成树的限制,我们仅仅需要满足路径上不出现“从某个连通块出来又重新进去”这种事情。
有一个显然的状压 DP,设 \(f[s][u]\) 表示经过的连通块集合为 \(s\),现在处于点 \(u\). 其实严格来讲这是一张图,需要在上面跑最短路(因为需要处理 \(s\) 相同 \(u\) 在同一连通块内的转移)。
问题是连通块个数太多了。一个很自然的想法是大小为 \(1\) 的连通块可以用一些手段缩去,但这还不够。事实上,大小不超过 \(3\) 的连通块都是不需要记录进 \(s\) 中的。因为如果从这个连通块里出去再回来至少要花费 \(2b\) 的代价,而这个连通块内任何两点的距离不超过 \(2a\).
因此 \(s\) 只需要记录大小 \(\ge 4\) 的连通块是否经过过的状态。这样的连通块最多只有 \(\frac{n}{4}\) 个。
时间复杂度 \(O(2^{\frac{n}{4}}m)\).
代码: 76698798

E

结论:设 \(f(u)=\text{mex}_{v\in out[u]}f(v)\),则可以把每个点表示为 \(a_k\omega^{f_k}\),就相当于一个只有第 \(f_k\) 个位置为 \(a_i\) 其余都为 \(0\) 的数组(这里的 \(\omega\) 在博弈论里还有一些其他的神奇意义),则先手胜当且仅当对于每个位置,所有的点的异或和均为 \(0\) (即 \(\forall i,\bigoplus_{f[u]=i}=0\)).
证明详见官方题解。
代码: 76707873

猜你喜欢

转载自www.cnblogs.com/suncongbo/p/12702242.html