杂题题解 2
FoxAndCity
设 \(d_x\) 表示 \(1\) 到 \(x\) 的最短距离,对于任何一张连通图都有:\(d_x \in [0,n),d_1=0\),若存在边 \((x,y)\),则有 \(|d_x-d_y|\leqslant 1\)。可以发现这是 \(d_x\) 合法的充要条件,已知满足上述限制的 \(d_x\) 时可以按 \(d_x\) 从小到大来依次加点构造出其对应的图。于是问题就转化为了构造满足以上限制的 \(d_x\),使其费用最小。像 [HNOI2013] 切糕 一样建图跑最小割即可。
[2017 山东二轮集训 Day1] 第三题
构造 \(g(n)\) 满足 \(f(n)=\prod\limits_{d\mid n}g(d)\),莫比乌斯反演得 \(g(n)=\prod\limits_{d\mid n}f(d)^{\mu\left(\frac{n}{d}\right)}\),考虑对 \(\text{lcm}\) 进行 \(\text{min-max}\) 容斥来转化为 \(\gcd\):
考虑最后的指数,设 \(S\) 中能被 \(d\) 整除的有 \(t\) 个数,得:
因此有:
CF1327F AND Segments
先拆位,然后用差分算出每个位置是否必须为 \(1\)。设 \(f_i\) 表示前 \(i\) 个位置合法,且第 \(i\) 个位置为 \(0\) 的方案数,合法的转移位置具有单调性,复杂度为 \(O(kn)\)。
[NOI2009] 管道取珠
平方的含义就是对于一种操作方式来说有多少种操作方式和其结果一样。可以 \(DP\) 求出有多少种操作方式能得到给定的结果,设 \(f_{i,j}\) 为取了 \(i\) 次,取了上管道 \(j\) 次即可。对于原问题,考虑 \(DP\) 套 \(DP\),设 \(g_{i,j,k}\) 表示取了 \(i\) 次,给定结果的那个操作方式已经取了上管道 \(j\) 次对应的所有 \(f_{i,k}\) 的和,枚举每次取上管道还是下管道转移即可。
[SNOI2019] 纸牌
出现三次的顺子看作三个刻子,因此顺子出现次数只能为 \(0,1,2\)。设 \(f_{i,j,k}\) 表示考虑了前 \(i\) 种牌,\(i-1\) 开始有 \(j\) 个顺子待匹配,\(i\) 开始有 \(k\) 个顺子待匹配的方案数,用矩阵快速幂转移即可,特殊处理有初始牌的位置。其实也是 \(DP\) 套 \(DP\),内层 \(DP\) 是可行性。
Rikka with String
只要算出在 \(i\) 左侧和右侧同时出现的子串个数就能计算位置 \(i\) 的答案。在 \(SAM\) 上每个节点维护出 \(\text{endpos}\) 集合的最小值 \(L_x\) 和最大值 \(R_x\),设 \(l=\min(R_x-L_x,len_{x})\),得该节点的贡献为:\([L_x+1,R_x-len_{fa}]\) 加上 \(l-len_{fa}\),\([R_x-l+1,R_x-len_{fa}]\) 加上首项为 \(-1\),公差为 \(-1\) 的等差数列,差分维护就能做到线性。
[ARC066D] Contest with Drinks Hard
求出 \([1,i]\) 的答案 \(f_i\),\([i,n]\) 的答案 \(g_i\),必须选 \(i\) 的答案 \(h_i\) 后就能快速回答询问了。用斜率优化就能求出 \(f_i,g_i\)。暴力求 \(h_i\) 的做法就是枚举 \(l\leqslant i \leqslant r\),用 \([l,r]\) 的贡献加上 \(f_{l-1}+g_{r+1}\) 来更新 \(h_i\)。考虑分治,对于分治区间 \([L,R]\),只维护出 \([L,mid]\) 的凸包,去更新 \([mid+1,R]\) 的值,这样就保证了 \(l\in[L,mid],r\in[mid+1,R]\),同理还需维护出 \([mid+1,R]\) 的凸包,去更新 \([L,mid]\) 的值。
[ARC066D] Contest with Drinks Hard
CF1110F Nearest Leaf
建线段树,叶子节点权值为根节点到其的距离,非叶子节点权值为正无穷。询问离线,\(dfs\) 时在线段树上加减对应的权值来实现换根。
[2017 山东二轮集训 Day7] 国王
设 \(a_{l,r}\) 为两个端点都在区间 \([l,r]\) 内的合法路径数,\(b_{l,r}\) 为两个端点都不在区间 \([l,r]\) 内的合法路径数,\(cnt_i\) 为以 \(i\) 为其中一个端点的合法路径数,不难得 \(2(a_{l,r}-b_{l,r})=\sum\limits_{i\in [l,r]}cnt_i -\sum\limits_{i\not\in [l,r]}cnt_i\),因此满足 \(\sum\limits_{i\in [l,r]}cnt_i -\sum\limits_{i\not\in [l,r]}cnt_i>0\) 的区间就是合法的。点分治求出 \(cnt_i\) 后双指针统计即可。
[NEERC2017] Journey from Petersburg to Moscow
枚举每种边权 \(w\),\(\leqslant w\) 的边权值改为 \(0\),\(>w\) 的边权值减去 \(w\),新图的最短路加上 \(kw\) 看作这种边权的权值,每种边权的权值取 \(\min\) 即为答案。考虑到不符合要求的情况一定劣,因此其不会被统计到。因为路径边数可能 \(<k\),所以还要把 \(0\) 加到枚举的边权里。
[NEERC2017] Journey from Petersburg to Moscow
CF778C Peterson Polyglot
直接对每个深度进行 \(Trie\) 树合并统计答案即可,复杂度证明类比 \(dsu\ on\ tree\),其他儿子合并到重儿子上,复杂度为轻儿子子树大小和 \(O(n\log n)\)。
[2017 山东三轮集训 Day6] C
可持久化 \(01\ Trie\) 维护来回答询问,异或直接全局打标记即可。剩下的只有 \(and\ 0\) 和 \(or\ 1\) 有用,发现执行这样的操作后同层节点都只会有一个儿子,另一个儿子会合并过来,因此每次重构后,对于该层的操作打标记即可。重构次数只有 \(O(\log n)\) 次,所以复杂度有保证。
[2017 山东一轮集训 Day1 / SDWC2018 Day1] Set
设所有数的异或和为 \(s\),若 \(s\) 的某一位为 \(0\),则 \(x_1,x_2\) 这一位要么都是 \(0\),要么都是 \(1\),因为要总和最大,所以要尽可能选 \(1\),等价让 \(x_2\) 这一位尽可能为 \(1\)。若 \(s\) 的某一位为 \(1\),则 \(x_1,x_2\) 这一位一个为 \(0\),一个为 \(1\),因为要 \(x_1\) 尽量小,等价让 \(x_2\) 这一位尽可能为 \(1\)。总的策略是让 \(x_2\) 先在 \(s\) 为 \(0\) 的位尽可能为 \(1\),再在 \(s\) 为 \(1\) 的位尽可能为 \(1\)。用线性基来实现,插入和查询时先考虑 \(s\) 为 \(0\) 的位即可。
[2017 山东一轮集训 Day1 / SDWC2018 Day1] Set
[2017 山东一轮集训 Day1] Sum
暴力 \(DP\) 就是设 \(f_{i,j,k}\) 为当前考虑到第 \(i\) 位,模 \(p\) 为 \(j\),数位和为 \(k\) 的方案数,转移即为枚举下一个要填的数 \(l\):
因为 \(n\) 过大,考虑倍增:
发现第三维是卷积的形式,用 \(NTT\) 优化即可。
前夕
设交集大小钦定为 \(k\) 的方案数为 \(k\) 为 \(f(k)\),交集大小恰好为 \(k\) 的方案数为 \(g(k)\),二项式反演得:
\(NTT\) 可以做到 \(O(n\log n)\),但题目要求线性。设容斥系数 \(\alpha(i)\),其满足:
考虑 \(g(i)\) 的贡献,得:
二项式反演得:
因此复杂度就能做到线性了。
[雅礼集训 2017 Day5] 珠宝
将体积相同的物品一起处理,价值从大到小排序。考虑到体积为 \(p\) 的物品时,将模 \(p\) 余数相同的状态分为一类来转移,设余数为 \(q\),状态都形如 \(pi+q\)。发现转移具有决策单调性,因为相同体积的物品取的越多,价值越小。复杂度为 \(O(ck\log k)\)。
[ICPC2018 WF] Gem Island
形如 \(x_1+x_2+\cdots+x_n=n+d\) 的最终序列的方案数为 \(\binom{d+n-1}{n-1}\),可以证明这些序列成为最终序列的概率相同。先将每个数减一来将正整数转化为非负整数,设 \(f_{i,j}\) 为所有满足 \(x_1+x_2+\cdots+x_i=j\) 的非负整数序列的前 \(r\) 大的值和的总和,枚举序列中非零位置个数 \(k\) 来转移:
将非零位置都减一就化为子问题了,第二项是子问题序列的贡献。
CF917D Stranger Trees
之前写过一个 \(O(n^4)\) 的,再记一个 \(O(n^2)\) 的:算出钦定有 \(i\) 条边重合的方案数后二项式反演就能求得答案,钦定有 \(i\) 条边重合等价于有 \(n-i\) 个连通块,就是把重合边断掉后剩下的任意连生成树。\(k\) 个连通块的方案数为 \(n^{k-2}\prod\limits_{i=1}^ka_i\),注意到 \(\prod\limits_{i=1}^ka_i\) 的组合意义是在每个连通块内选出一个点,因此用一个 \(O(n^2)\) 的树形背包就能求解了。
[CEOI2019] Magic Tree
考虑 \(DP\),设 \(f_{x,i}\) 表示 \(x\) 的父边在 \(i\) 时刻断其子树内的最大收益,发现转移是 \(\max\) 卷积,线段树合并实现整体 \(DP\) 即可。也可以用 \(map\) 维护差分值来启发式合并。
[Ynoi2011] 竞赛实验班
任意时刻序列都是形如前一段有经过排序,后一段没有经过。对于后一段只需对每一位记录前缀和即可,前一段用 \(01\ Trie\) 维护,查询就是查前 \(k\) 小的和,在 \(01\ Trie\) 上二分即可,这里需要维护 \(01\ Trie\) 上每个点子树内有多少个数在某一位为 \(1\)。打全局标记来实现整体异或,排序只需将无序部分插入到 \(01\ Trie\),每个数只会被插入一次,因此复杂度有保证。
共价大爷游长沙
边 \((x,y)\) 有被所有路径覆盖当且仅当以 \(x\) 为根时,所有路径的端点都恰好有一个在 \(y\) 的子树内。给每条路径的两个端点随机相同的权值,查询就是看对应的子树异或和是否等于当前所有路径的异或和,用 \(LCT\) 维护即可。
[雅礼集训 2018 Day10] 贪玩蓝月
首先有个 \(O(pm\log m)\) 的线段树分治的做法。实际上本题可以在线做到 \(O(pm)\),维护两个栈来实现双端队列,当弹栈时一个栈为空时,将另一个栈分一半的元素到该栈里,势能分析后复杂度是对的,具体证明可以看 yhx 的题解,查询用单调队列查询最值即可,要注意的就是下标是在模意义下的,合法区间可能是两段区间。
[PKUSC2018] PKUSC
转化为多边形不转,点转,这样的话只需对每个圆计算多边形覆盖了多长的圆弧。可以直接求出多边形和圆的交点,然后判断每段弧是否在多边形内,这样做复杂度是 \(O(nm^2)\) 的。实际上有复杂度为 \(O(nm)\) 的做法:将多边形以圆心为中心来三角剖分,对于一个端点为圆心的三角形和圆圆弧交的长度是好算的,类似叉积求多边形面积根据顺逆时针加减即可。
算三角形的圆弧交时,只需对 \(\alpha_1,\alpha_2,\alpha_3\) 这三个角进行讨论即可。
CF1463F Max Correct Set
考虑 \(DP\),设 \(f_{i,S}\) 表示前 \(i\) 个数的最大长度,且前 \(\max(x,y)\) 个数的选择情况为 \(S\)。但 \(n\) 过大,不能直接 \(DP\),可以证明最优的选择是有长度为 \(x+y\) 的周期,证明可以看官方题解。因此就只用 \(DP\) 周期部分,就能通过本题了。