2 月做题记录
2.1-2.9
P5996 [PA 2014] Muzeum
不错的题目,拆一下式子,然后贪心模拟费用流即可。
P10367 [PA 2024] Żarówki
和 AGC004F 一个套路,(a,b) 连边,然后每个连通块单独考虑,交替染色,考虑如果是二分图,则可以任意移动,方案数是组合数,否则颜色数奇偶性不能变,\(2^{n-1}\)。
P5985 [PA 2019] Muzyka pop
没见过这个模型,考虑在 Trie 上做区间 dp,非常神奇。
P9252 [PA 2022] Wielki Zderzacz Termionów
那个经典结论,在 \(\bmod 3\) 下考虑,然后删除掉 \(ABABA\) 的情况即可。
P6822 [PA 2012 Finals] Tax
神秘建图题,对于边建点,然后对于每个点,可以按边权排序后相邻连边。
AT_agc013_d [AGC013D] Piling Up
比较奇怪的题,画出折线图,然后由于初始位置不定,所以需要一定到达过 \(0\) 的才计数,否则会算重。
AT_agc028_d [AGC028D] Chords
考虑对于每个连通块,最外层的 \([l,r]\) 计数,考虑满足哪些条件:
长度为偶数,不存在点向外连边,\(l,r\) 联通。
前两个条件好计算,最后一个考虑容斥,枚举 \(l\) 所在连通块最右端 \(i\),作代表元容斥即可。
AT_agc009_e [AGC009E] Eternal Average
首先不难发现我们建出一个树结构,我们得到的形如 \(\sum (\frac 1 k)^{d_i}\)。
问题在于如果一层进位了,那么就会重复。这样的话我们不考虑进位,枚举进位的次数删除其影响,求和即可。
P9824 [ICPC 2020 Shanghai R] Fountains
shaber 题,从大到小考虑,然后状压即可。
AT_arc168_f [ARC168F] Up-Down Queries
我感觉,这个题,很困难。
首先维护差分数组,等价每次插入 \(2\) 个 \(a_i\),然后取出最小的数。
不难发现可以建出费用流模型,然后做模拟费用流即可。
改变某个边权的时候可以线段树分治 \(O(n\log^2 n)\),更好的做法是先退流,然后考虑左右两边都能怎么增广。
P8633 [蓝桥杯 2015 国 B] 模型染色
shaber polya,直接 \(n!\) 枚举即可。
P5496 【模板】回文自动机(PAM)
复习了一下 PAM 板子。
P4694 [PA 2013] Raper
模拟费用流经典题。
P11608 [PA 2016] 雨后的蘑菇 2 / Grzyby po deszczu 2
等价于 CF573E,知道凸性,然后平衡树上二分即可。
由于区间加等差数列不好写,可以维护差分数组。
P4384 [八省联考 2018] 制胡窜
可以 \(2^3\) 容斥一下,然后接下来就是一些分讨,线段树合并维护。
P5331 [SNOI2019] 通信
简单优化建图费用流题目。
P4718 【模板】Pollard-Rho
似乎会这个板子了,而且比较好写。
Code
const int pr[11]={2,3,5,7,11,13,17,19,23,29,31};
inline bool M_R(int p){
if(p<=1) return 0;
for(int i=0;i<11;++i)
if(p==pr[i]) return 1;
else if(!(p%pr[i])) return 0;
int d=p-1,c=0;
while(!(d&1)) ++c,d>>=1;
for(int i=0;i<11;++i){
int x=qp(pr[i],d,p);
for(int j=0,y=0;j<c;++j,x=y)
if((y=mul(x,x,p))==1&&x!=1&&x!=p-1) return 0;
if(x!=1) return 0;
}
return 1;
}
inline int work(int p){
int x=rng()%(p-1)+1,y=x,d=1,c=rng()%p+1;
for(int k=1,val=1;;k<<=1,y=x,val=1){
for(int i=1;i<=k;++i){
x=(mul(x,x,p)+c)%p,val=mul(val,x>y?x-y:y-x,p);
if(!(i%127)&&(d=gcd(val,p))>1) return d;
}
if((d=gcd(val,p))>1) return d;
}
return d;
}
inline void calc(int p){
if(p==1) return;
if(M_R(p)) return vec.pb(p),void();
int d=work(p);
calc(d),calc(p/d);
}
P4607 [SDOI2018] 反回文串
AT_nikkei2019_qual_f Jewels
似乎是反悔贪心题目,但是一个神秘做法是猜测对于 \(\bmod 6\) 有凸性,闵可夫斯基和即可。
AT_arc098_d [ARC098F] Donation
倒过来做,建出 Kruskal 重构树,然后简单 dp。
P8478 「GLR-R3」清明
非常好做法,爱来自 uob
写出 GF:
我们考虑后面部分,等价于对于每一个 \(i\) 选择一个 \(k\),使得乘上 \(\frac {x_k}{1-x_k}\),那么对于每一个 \(x_k\),不难知道贡献只和后面被选择的次数有关。
然后考虑 \(k\) 被选择 \(t_k\) 次,则贡献是:
然后我们就可以 dp 了。
从 \(1\sim n\) 考虑,考虑维护当前 \([i,i+m]\) 的覆盖状态,每次枚举一个状态 \(S\) 当作当前覆盖情况,然后转移就是子集卷积,复杂度 \(O(nm^22^m)\)。
\(m\le \frac n 2\) 可以接受,我们考虑 \(m\ge \frac n 2\) 的情况,发现此时 \(1\le m+1\) 的位置都是可以随便覆盖的。
所以我们可以只状压 \([m+2,n]\) 的位置,然后对于 \([1,m+1]\) 的位置,背包有 \(j\) 个数还没选择即可,这样复杂度也是 \(O(2^{\frac n 2}m^3)\) 的,可以通过。
具体来说是 \(O(2^{n-m-1}(2n-m)^3(n-m-1)^2+m(n-m-1)^22^{n-m-1})\),证明一下发现是 \(O(2^{\frac n 2}n^3)\) 的。
当然由于子集卷积非常慢,跑不过 \(O(3^n)\) 的暴力。
P8293 [省选联考 2022] 序列变换
建出括号树,然后考虑两种操作的实质。
- 对于两个相邻儿子,把一个和其儿子接到另外一个下面。
- 交换两个相邻儿子。
最后我们需要树变成一条链。
由于我们可以任意交换儿子之间的顺序,所以和顺序无关。
考虑对于 \(x,y\) 取值分讨。
- \(x=0,y=0\),答案为 \(0\)。
- \(x=0,y=1\),代价是被下发的数的权值,不难知道每次留下最大值即可。
- \(x=1,y=1\),代价是所有数的和+\((sz-2)\times \min v\),由于我们需要 \(\min v\) 最小,且以后所有数的和最小,留下最大值即可。
剩下是最难的部分。
我们发现权值是 \((sz-2)\times \min v\) + 留下的权值。
由于我们想要 \(\min v\) 小,所以我们想下放最小值。
由于最后一层的点无代价,所以我们想要下放最大值。
所以我们考虑怎么办。
考虑每层决策大小形如 \(1\ldots 1,2,\ldots ,2,\ge 3,\ge 3,\ge 3,\ldots 2,1\)
排除掉前面的 \(1\),最后两层决策容易知道,\(\ge 3\) 时我们可以同时下放最大最小。
然后我们的问题变成那一段 \(2\) 给 \(\ge 3\) 的第一个下放了什么。
由于我们可以使用 exchange argument,证明那一段 \(2\) 只会把最大或者最小值传下来。
所以我们只有 \(O(1)\) 种决策,做一遍即可。
P11038 【MX-X3-T5】「RiOI-4」Countless J-Light Decomposition
跟 APIO 那个题一个套路,可以只保留度数 \(\ge k\) 的点,总点集大小是 \(O(n)\) 的,然后在上面用平衡树优化 dp 即可。
P9168 [省选联考 2023] 人员调度
模拟费用流,考虑每个人向节点连 \((1,w)\),每个节点向父亲连 \((sz_x,0)\),然后做费用流即可。
考虑优化,如果加入一条边,找到最大的不能流的祖先,在其子树内找一条流代替即可。
删除不好做,考虑线段树分治,\(O(n\log^3 n)\)。
理解之后很好写,写+调只需要 \(35 \min\) 左右。
似乎可以直接换全局平衡二叉树做到 \(O(n\log^2 n)\)。
要实现链加,找到第一个为 \(0\) 的祖先。
每个点维护当前重链在该子树内的最小值和 tag,像 LCT 一样认父不认子,然后修改可以直接打 tag,询问可以先跳到根的路径,在上面 pushdown,然后分成为为左儿子右儿子还是轻儿子即可。
应该不难写。
CF1338E JYPnation
首先考虑这玩意形如一条链最后跟一个 SCC 形式,证明不难。
然后可以考虑两个点的贡献,存在一个点在链上的答案是容易计算的。
问题在于 SCC 内部的点的贡献,可以证明任意两点距离 \(\le 3\)。
计算距离为 \(1,2\) 的即可。
CF1179D Fedor Runs for President
可以先对一条路径 \((x,y)\),找到其贡献形式是什么。
然后可以在 lca 处考虑贡献,发现决策可以斜率优化即可。
CF932G Palindrome Partition
回文划分,运用了回文的 border 组成 \(O(\log n)\) 个等差数列的性质。
建 pam 的时候可以维护 slink 表示这条链链顶的父亲。
然后考虑 dp 的时候贡献转移,发现只比上一次访问这一条链多错位了一个位置,剩下的都可以用上一次的信息继承过来即可。
还有同样的题目 CF906E Reverses
CF827F Dirty Arkady's Kitchen
对于每个点拆点成为奇数和偶数,考虑每条边给每个点贡献一个 \([x,l,r]\) 的三元组,表示 \([l,r]\) 的时间可以在 \(x\),按 \(l\) 从小到大转移。
2.10-2.16
AT_arc160_f [ARC160F] Count Sorted Arrays
首先经典套路是对于所有 \(i\),把 \(\le i\) 看成 \(0\),\(>i\) 的看成 \(1\),序列要有序。
然后我们对于每个初始的 01 序列 \(S\),维护 \(S\) 经过变化后现在的值。
那么一个初始时的序列合法当且仅当他每个时刻的序列现在都合法。
然后我们枚举 \(S\) 表示初始存在 \(S\) 作为 01 序列,枚举 popcount 少一个的数转移即可。
此时我们是 \(O(mn2^n)\) 的,我们可以猜测实际上把 \(S\) 变化的有效操作不会很多,加上这个判断即可通过,似乎有效操作只有 \(O(n^2)\) 个。
P7521 [省选联考 2021 B 卷] 取模
从大到小考虑模数,如果此时模数不大于此时的答案或者这个模数计算过就退出。
可以证明只会选取 \(O(\log V)\) 个模数,证明看的题解,这里鸽了。
P7294 [USACO21JAN] Minimum Cost Paths P
设每个行最远跑到 \(c_y\) 的地方,那么推一下式子,发现就是形如 \(L_2\) 的链上的保序回归问题,浮点问题可以四舍五入,套用论文做法即可。
有个取值上下界,可以在单调栈上二分,同时记录前缀和,剪掉。
P3748 [六省联考 2017] 摧毁“树状图”
感觉不错的树形 dp 题目,分成是否经过某个点。
是的话选取前 \(4\) 大,否则一定可以一条路径 lca 是某个点,另外一条在其子树外面。
一个比较好写的做法是换根。
P4363 [九省联考 2018] 一双木棋 chess
直接跑状压 dp 是 \(O(n\binom {n+m}n)\) 的。
P9169 [省选联考 2023] 过河卒
有向图博弈板子,需要状态 /2 以优化常数。
P4382 [八省联考 2018] 劈配
可以直接匈牙利。
P5289 [十二省联考 2019] 皮配
背包,除了有限制的都可以分开派系和阵营,剩下的部分暴力背包即可。
P5533 [CCO 2019] Winter Driving
有一个性质:最优解存在一个点作为根,其每个子树要不然是内向树,要不然是外向树。
然后我们算一下贡献,发现需要以某个点为根的时候,划分剩下子树,使得两个集合大小尽量接近。
除了重心之外,都可以某个较大子树单独分组。
对于重心,我们折半搜索即可。
P8500 [NOI2022] 冒泡排序
转化成为逆序对数量。
考虑 B 性质,说明钦定了一些点,剩下的部分,我们从后往前考虑,我们发现我们可以通过这些钦定的位置,贪心选择代价最小的,如果有多个则选择最大的那一个,不难知道此时我们的选择是单调的,不会出问题。
考虑 C 性质,不难知道可以把最小值放在最前面最优秀,然后剩下的我们知道一些位置的取值 \(\ge val\) ,所以我们可以把这些位置先当成 \(val\),然后从后往前用上面的方法同理维护即可。
考虑区间有交,找出每个点最小的限制 \(val\),然后我们按 \(l\) 从大到小考虑,如果区间没有被选择过,选择其能选择的下标最小的那一个一定更优。
这样我们问题变成了钦定了某些位置,每个点有最小的限制,问最小逆序对,不难发现可以用上面的方法维护。
P8341 [AHOI2022] 回忆
CF2062F Traveling Salescat
考虑 \(\max(x,y)=\frac {(x+y)+|x-y|}{2}\)。
设 \(c_i=a_i+b_i,d_i=a_i-b_i\),则代价变成 \(\frac 1 2 (c_i+c_j+|d_i-d_j|)\)。
然后接下来的 dp 是容易的。
CF1276F Asterisk Substrings
考虑分成 \(\varnothing,*,S,S*,*S,S*T\) 计算。
前两个和为 \(2\),第 \(3,4,5\) 种等价于 \([1,n],[1,n-1],[2,n-1]\) 本质不同子串数量,SAM 计算。
考虑最后一种,建出 SAM,考虑每个等价类 \(x\),则此时 \(S\) 选择数是 \(len_x-len_{link_x}\)。
考虑 \(x\) 对应的 endpos 集合是 \(p_1,p_2,\ldots p_m\)。
然后 \(T\) 的选择方案数为在反串的 SAM 上 \({p_1+2,p_2+2,\ldots p_m+2}\) 对应的 endpos 到根的链并,这个可以在正串 SAM 上建线段树,维护反串的 dfn 序,然后线段树合并维护。
2.17-2.28
由于省选的问题,没缓过来,然后发现上个月的没写完/kx
P9482 [NOI2023] 字符串
首先,把比较子串字典序,转化成比较前缀和后缀的字典序,这样我们实际上只有本质不同的 \(O(n)\) 个数在比较。
然后我们考虑这样计算出来是小于等于的,因为可能出现比较部分相同的情况,此时我们考虑减去这一部分。
这玩意怎么做呢?观察到此时比较部分相同,则中间部分是回文的,那么我们可以同时在比较的字符串前面插入相同的字符串,字典序相对大小不变,然后计数就是一个二维数点了。
P6631 [ZJOI2020] 序列
线性规划对偶板子题,可以证明对偶之后的取值只有 \(\{-1,0,1\}\),直接 dp 即可,复杂度 \(O(n)\)。
P7246 手势密码
可以直接线性规划,对偶后大概可以证明取值只有 \(\{-1,0,1\}\),然后可以直接 dp。
贪心也是可以的,而且并不困难。
P6970 [NEERC 2016] Game on Graph
有向图博弈,先 bfs 求出每个点是否选择一直走,然后再做一次求胜负。
P11622 [Ynoi Easy Round 2025] TEST_176
平衡树有交合并板子题,考虑在 \(l\) 处加入,\(r\) 处计算答案,注意权值相同的要用并查集合并,不然似乎复杂度有问题?
合并时就是找到根节点,把另外一棵树分开,然后合并到左右子树上,势能分析一下复杂度是对的。
AT_agc018_e [AGC018E] Sightseeing Plan
首先点到矩形的方案数可以转化成点到四个点的方案数。
枚举中间的矩形,分开计算进入位置和出去位置的贡献即可。
P9962 [THUPC 2024 初赛] 一棵树
暴力 dp 是简单的,转移代价是凸的,可以合并堆维护差分数组。
由于这玩意被分成了两段,可以可并堆维护。
P5611 [Ynoi2013] D2T2
暴力做法考虑 \(O(n\sqrt n\log n)\) 的莫队和 \(O(n\sqrt m)\) 的KDT,显而易见都过不去。
首先我们知道一个区间最大子段和可以用 \((lmx,rmx,sum,ans)\) 的四元组表示。
考虑分块,块长为 \(B\),那么我们一次就需要计算我给定 \(m\) 个值域区间 \([L,R]\),每个值域区间的四元组。
我们可以知道,实际上我们只有 \(O(B^2)\) 个本质不同的对。
考虑如何快速计算每个对,我们对于序列分治,然后每次考虑计算出此时的 \(f_{l,r}\) 表示在第 \(l\) 个数到第 \(r\) 个数的值域中,我们得到的四元组,然后分治的时候,\(f_{l,r}\) 可以简单的从左边和右边的 \(f'\) 合并上来。
复杂度为 \(T(B)=2T(\frac B 2)+\mathcal O(B^2)=\mathcal O(B^2)\)
总复杂度为 \(\mathcal O(nB+mB+\frac {mn}B)=\mathcal O((n+m)\sqrt n)\)
常数不大。
AT_abc224_h [ABC224H] Security Camera 2
线性规划对偶一下发现是简单流子题,就这样。
AT_wtf19_b Multiple of Nine
AT_abc378_g [ABC378G] Everlasting LIDS
首先我们知道双杨表和序列的双射,那么其中一个杨表可以勾长公式计算,另外一个找下性质之后可以简单 dp。
AT_arc144_e [ARC144E] GCD of Path Weights
AT_arc165_e [ARC165E] Random Isolation
等价于按一个随机排列的顺序进行操作,然后可以 dp 了,考虑子树内部选择了 \(m\) 个节点,连通块大小为 \(n\) 的概率,然后可以 dp。
AT_arc190_d [ARC190D] Matrix Pow Sum
考虑拆贡献,\(\sum_{i=1}^{p-1}i^k \bmod p\) 只有在 \(k=p-1\) 时不等于 \(0\)。
所以我们知道我们如果选择一个未知数的话就要选择 \(p-1\) 次,然后计算就是简单的了。
AT_arc192_d [ARC192D] Fraction Line
简单题,对于每个质数分开 dp 即可。
P5170 【模板】类欧几里得算法
学习了万欧,大概是 \(p>q\),\(R\gets U^{\frac p q}R\),否则考虑转变坐标系即可。
复杂度是 \(O(\log n)\) 的。
P9170 [省选联考 2023] 填数游戏
对于 \(b\) 的两个数连边,分开考虑每个连通块。
如果 \(E<V\) 无解,剩下就是 \(E=V\) 或者 \(E=V-1\)。
然后 A 的影响是每次可以在 \(B\) 的一条边上,两个中选一个,只能选固定一个,或者不能选择。
基环树的情况是简单的,剩下最大问题是树的情况,这个部分比较困难。
暴力做法是 \(O(n)\) 枚举根,然后 dfs 计算每个点的代价,直接换根即可做到 \(O(n)\),但是细节有点多。

浙公网安备 33010602011771号