[一直更新中]一句话题解
一句话题解
不能什么题都随便写写就过了,留点印象好一点。一直更新。
2024.10.29
AT_abc290_f
组合数数。满足树的形态要有 \(\sum deg_i=2n-2\)。考虑目前有 \(k\) 个儿子节点,直径最大肯定是 \(n-k\) 个非儿子点串一条长度为 \(n-k+1\) 的链,然后再挂儿子节点。总度数 \(2n-2\),给 \(n-k\) 个非儿子节点支配的还剩 \(2n-2-k\),易得插板:\(\binom{(2n-2-k)-2(n-k)+(n-k)-1}{(2n-2-k)-2(n-k)}=\binom{n-3}{k-2}\)。答案即为:\(\sum\limits_{k=1}^n \binom{n}{k}\binom{n-3}{k-2}(n-k+1)\)。
根据吸收恒等式(\(k\binom{n}{k}=n\binom{n-1}{k-1}\))和范德蒙德卷积(\(\sum\limits_{i=0}^k\binom{n}{i}\binom{m}{k-i}=\binom{n+m}{k}\))可以化简成 \(O(1)\):\(Ans=(n-1)\binom{2n-3}{n-1}-(n-3)\binom{2n-4}{n-1}\)。
AT_arc156_c
构造。观察可得价值最小无论如何都是 \(1\)。方向转为构造排列。观察树是链的情况,排列直接为序号翻转过来。考虑树普通情况,每次取两个叶子节点交换序号即可。类似拓扑地,可以处理至原树变成一条链。
正确性证明:一条 \(u\to v\) 的简单路径,路上的编号大概形如 \(v\to u\) 的路径的编号。刚好是完全相反的,满足了 LCS 为 \(1\)。
2024.10.30
Luogu P5749 [IOI2019] 排列鞋子
贪心。对于每种大小用 vector 存鞋的位置,从后往前遍历,每次可配对鞋一定在 vector 最后一个最优。贪心显然成立。可以用树状数组优化求区间 \(1\)(交换次数)操作。
AT_abc285_e
DP。可设 \(S_i\) 表示一周 \(i+1\) 天只有一天休息日的贡献。易得 \(S_i=2\sum\limits_{j=1}^{\lfloor\frac{i}{2}\rfloor}a_j+[i\bmod 2=1]a_{\lceil\frac{i}{2}\rceil}\)。设 \(F_i\) 表示一周有 \(i\) 天的贡献,初始状态有 \(F_i=S_{i-1}\)。可以枚举休息日的个数:\(F_i=\max\limits_{j=2}^{i-2} F_j+F_{i-j}\)。答案为 \(F_n\)。
CF79D
状压 DP + 差分 + 图论建模。对区间翻转的操作,可以把序列转为差分序列后单点修改。设让 \((i,j)\) 两位同时翻转的代价为 \(w(i,j)\),再设已清零状态为 \(ste\) 的最小代价为 \(f_{ste}\)。可得:\(f_{ste}=\min\limits_{i,j} f_{ste-2^i-2^j}+w(i,j)\)。对于 \(w(i,j)\) 我们采用图论建模:若 \(|u-v|=l_i\),则 \(u,v\) 之间有边权为 \(1\) 的边。那么可由 \(v\) 再拓展到其他边,这样对于每个起点 \(s\) 求出来的最短路 \(dis_i\) 即为两点同时翻转的最小操作次数。所以跑 \(n\) 轮 SPFA 即可得到 \(w(i,j)\)。
CF1109E
线段树。除数如果和模数互质,那么转换为乘逆元的操作,非常好做。注意到模数不同的质因子不超 \(9\) 个,现在把模数唯一分解,对于操作除数可以先把含有的模数因子剔除出来,剩下的数就可以乘逆元。是因子的数我们存他的指数,除到了他们就是指数减减。要计算权值的时候跑个快速幂把他们乘起来。
CF853C
二维数点。算相交不好算,就算不相交的。显然在矩形的某一边的一侧或角落上,减去四边上的后多减了一次四角,所以要再加回来。由于可以旋转坐标系,所以我们只考虑左下角。我们把矩形按左下角横坐标排序,双指针维护点横坐标始终小于等于矩形左端,左边的不相交矩形个数是 \(\binom{i-1}{2}=\frac{(i-2)(i-1)}{2}\),左下角的矩形个数是 \(\binom{k}{2}=\frac{k(k-1)}{2}\)。\(k\) 表示横纵坐标都小于当前矩形左下角横纵坐标的点数。如何求 \(k\)?二维偏序,可以树状数组维护。
Luogu P2757 [国家集训队] 等差子序列
线段树 + 哈希。题意容易转换为找排列中有没有长度为 \(3\) 的等差序列。这类题可以想到遍历中间那个数,如果 \(a_i-k\) 已遍历(在左边)、\(a_i+k\) 未遍历(在右边)就合法,当然大小顺序倒过来也一样。考虑优化掉 \(k\) 的枚举。假设我们现在用一个长为 \(n\) 的 01 数组来表示下标为 \(i\) 的数是否访问过。我们考虑对一个值为 \(1\) 的地方将整个数组折叠,如果重合的地方只有其中一个为 \(1\) 那么我们就找到了长为 \(3\) 的等差序列。这一步可以用两个哈希比较,分别是从左到右的哈希和从右到左的哈希,如果哈希相同,证明找到了等差序列。这一步可以用线段树实现区间哈希。
CF1083C
线段树 + ST 表。查 mex 就是查一段最大前缀 \(1,2,\dots,k\) 使得这权值为 \(1,2,\dots,k\) 的 \(k\) 个点都在一条链上。考虑对每个 \(i\) 维护点权等于 \(i\) 的点在树上的编号,用线段树维护 \([l,r]\) 是否都在一条链上。考虑区间信息的合并:如果任意一个区间内的点都不构成链,必然合起来也不构成链。否则考虑两条链的端点 \(a,b,c,d\),任选两个作新链的端点,总共有 \(\binom{2}{4}=6\) 种可能,枚举即可,同时判断另外两个点是否在这条链上。
如何判断一个点是否在一条链上:\(dis(x,u)+dis(x,v)=dis(u,v)\) 是 \(x\) 在路径 \((u,v)\) 上的充要条件。用欧拉序 +ST 表 \(O(n\log n)\sim O(1)\) 求 LCA 即可。
CF830D
DP。设 \(f_{i,j}\) 表示 \(i\) 层的树能选出多少组不相交的 \(j\) 条路径。可以由两棵 \(i-1\) 层的树合并成 \(i\) 层的树。共有 \(4\) 种转移:1. 直接转。 2. 增加一条路径,即根节点自己。 3. 将根节点和一条路径合并。 4. 将根节点和两条路径合并。转移方程分别为(\(t=f_{i-1,j}\times f_{i-1,k}\)):
- \(f_{i,j+k}=t\)
- \(f_{i,j+k+1}=t\)
- \(f_{i,j+k}=2t(j+k)\)
- \(f_{i,j+k-1}=2t\binom{j+k}{2}\)
目标状态为 \(f_{n,1}\)。
2024.10.31
CF513E2 & E1
DP。这个做法可以过 E1。遇绝对值拆绝对值,我们发现真正有贡献的段是比相邻都大或都小的段。抽象成折线图,“峰”可以贡献 \(+2s_i\),“谷”可以贡献 \(-2s_i\),其余(“升”、“降”)的贡献均为 \(0\)。当然 \(s_1\)、\(s_k\) 的贡献另说。根据发现,可设 \(f_{i,j,0/1/2/3}\) 表示第 \(i\) 个数属于第 \(j\) 段、当前这一段状态是“谷”、“升”、“峰”、“降”四种状态之一的最大答案。考虑方程:
对于“谷”的转移:
- 把 \(a_i\) 融入这一段,仍然是谷。
- \(a_i\) 新开一段,上一段可能是降或峰。
- 所以 \(f_{i,j,0}=-2a_i+\max\{f_{i-1,j,0},f_{i-1,j-1,3},f_{i-1,j-1,2} \}\)。
对于“升”的转移:
- 把 \(a_i\) 融入这一段,仍然是升。
- \(a_i\) 新开一段,上一段可能是谷或升。
- 所以 \(f_{i,j,1}=\max\{f_{i-1,j-1,0},f_{i-1,j-1,1},f_{i-1,j,1} \}\)。
后面两种情况类比上面的两种情况。初始状态为 \(f_{i,0,0/1/2/3}=0\),其余为无穷小。目标状态是 \(f_{i,k,0/2}\)。发现 \(i\) 总是由 \(i-1\) 转移而来,所以可以滚动压掉一维。
Luogu P9128 [USACO23FEB] Fertilizing Pastures G
贪心。不用走回根节点的情况显然把深度最大的一条链留到最后再走。设 \(sum_u\) 表示子树 \(u\) 的点权和,\(sz_u\) 表示子树大小。设 \(f_u\) 表示零时刻在 \(u\) 的最小代价。我们考虑访问子树的顺序使得 \(f_u\) 最小。若 \(u\) 的儿子为 \(p_{1,\dots,k}\),代价为:\(\sum\limits_{i=1}^kf_{p_i}+sum_{p_i}+\sum\limits_{i=1}^k 2sum_{p_i}\sum\limits_{j<i} sz_{p_j}\)。前面的 \(\sum\) 是确定的,后面的 \(\sum\) 取决于 \(p\) 的顺序。我们考虑 \(p_i\) 与 \(p_{i+1}\) 交换是否更优。我们钦定排在前面的更优,那么有 \(sum_{p_{i+1}}\times sz_{p_i}<sum_{p_i}\times sz_{p_{i+1}}\)。按 \(\frac{sum_i}{sz_i}\) 降序排序得到的 \(p\) 最优。
对于可以不用回到根节点的询问,把有最长链的儿子放到最后,考虑变化量。
Luogu P2737 [USACO4.1] 麦香牛块Beef McNuggets
DP。学到了一个 trick:在我们无法证明或不确定其正确性的时候,我们就大胆乱搞,程序能跑多少就跑多少,如果这个结论刚好被猜中,效益是很大的!解法:布尔完全背包。
Luogu P2727 [USACO3.2] 01串 Stringsobits
DP。首先杨辉三角预处理出组合数,那么从高位枚举可不可以放 \(1\),充要条件是 \(\sum\limits_{j=0}^L \binom{i-1}{j}>k\)。边做边输出。
Luogu P2732 [USACO3.3] 商店购物 Shopping Offers
DP。一定要相信自己的 idea!注意到商品数量极少,所以是五维完全背包 DP。如果不买这么多,可以看成是买 \(0\) 个对应物品。
Luogu P1930 [USACO3.3] 亚瑟王的宫殿
bfs。枚举汇集点,bfs 出每个马的最短步数。再枚举每个骑士 bfs 出国王在哪个点和骑士汇集。
2024.11.1
11 月了啊。
Luogu P6100 [USACO19FEB] Painting the Barn G
差分 + DP。差分可以把区修变单修。再通过前缀和和起来得到原数组,对于 \(k\) 和 \(k-1\),前者覆盖后贡献为 \(-1\),后者为 \(1\)。设 \(h_{l,r}\) 为 \(\max\limits_{i}s[i][l,r]\),设 \(w_{l,r}\) 为 \(\max\limits_{i}s[l,r][i]\)(\(s\) 是求和数组)。前者是限定了列,后者是限定了行。答案即为 \(cnt+\max\limits_i\{h_{1,i}+h_{i+1,200},w_{1,i}+w_{i+1,200} \}\),\(cnt\) 为原矩阵本来就等于 \(k\) 的数量。
2024.11.3
Luogu P5839 [USACO19DEC] Moortal Cowmbat G
DP + 前缀和/前缀 \(\text{min}\) 优化。先跑一边 floyd 求最短路。设 \(f_i\) 表示以 \(i\) 结尾的连续段的最小代价。DP 方程易得:\(f_i=\min\{ f_j+\text{get}(j+1,i)\}\),\(\text{get}\) 表示这一段都换成同一种颜色的最小代价。这里可以预处理前缀和 \(O(1)\) 查询。设 \(mn_j\) 表示颜色改为 \(j\) 的最小代价(前缀 \(\text{min}\)),可以 \(O(1)\) 转移:\(mn_j=\min\{mn_j+dis_{i,j},f_{i-k}+\text{get}(i-k+1,i,j)\}\),这里的 \(\text{get}\) 多传了颜色参数。
Luogu P7054 [NWRRC2015] Graph
拓扑排序变种。要求字典序小相当于在用小根堆做拓扑。考虑当前入度为 \(0\) 的点是否能被别的点连接,用大根堆存可以被连接的点。能被连接,充分条件是有一个比他大的节点且比他的访问顺序先(访问顺序后的节点再连会构成环)。以此来把当前入度为 \(0\) 的点纳入可被连接的范畴。如果有剩,优先输出剩的;否则输出可被连接的。连边可以按拓扑序上一个连有向边,正确性显然的。
2024.11.4
Luogu P8990 [北大集训 2021] 小明的树
线段树。视亮灯点为白点,不亮点为黑点。白点不好做,就考虑黑点。因为根节点始终为黑点,所以当满足限制时,黑点只构成一个连通块。怎么判断黑点只构成一个连通块?黑点数减“黑黑边”数就是黑连通块数。白连通块的数量本质上是“黑白边”的数量。有了这个结论,单次询问可以 \(O(n)\) 维护“黑黑边”数、“黑白边”数和黑点数并得到结果。现在带修,一次修改查询只能在 \(O(\log)\) 内完成。自然想到对于每个时刻维护以上三值。先考虑一条边的断/连会对以上三值有什么影响(只考虑连的情况,断是等价的)。
设 \(t_x\) 表示点 \(x\) 点亮的时刻,以下钦定一条边 \((x,y)\) 中 \(t_x<t_y\)。显然对于黑点数不会有影响。对于“黑黑边”数在 \([1,t_x-1]\) 会增一。对于“黑白边”数在 \([t_x,t_y-1]\) 会增一。由于维护黑点数和“黑黑边”数是为了得到黑连通块数,而其中一值不变,干脆直接维护黑连通块数与白连通块数。前者在 \([t_x,n-1]\) 会增一,后者在 \([t_x,t_y-1]\) 会增一。发现这两个东西都是区间维护,可以上线段树。具体地,维护黑连通块最小时大小、存在了几个时刻、以及当前区间黑连通块最小时的答案。
Luogu P7124 [Ynoi2008] stcm
分治。先得到每个点的 dfn 序,那么一个点及其子树内的节点的编号是连续的。他的子树补就是 \([1,dfn_u-1]\cup [dfn_u+sz_u,n]\)。可以分治。对于当前分治区间 \([l,r]\),处理被 \(mid\) 分开子树区间的点 \(u\)。暴力逼近点 \(u\) 的子树区间,这个过程输出操作 1 的答案。然后再撤销以上操作 1,暴力将右端点逼近至 \(mid-1\),然后递归分治左区间,同样输出,同样撤销;右区间同理。
2024.11.6
Luogu P2739 [USACO4.4] 棋盘游戏Shuttle Puzzle
dfs。注意不要写宽搜!剪枝是平凡的“深度大于等于最优答案”就回溯。对于优先级的问题搜索顺序调整一下即可。