绿色是自己做出来的,红色是自己没做出来的。
文化课选手做几个 OI 题陶冶情操,所以这里没几个题。
P8478 「GLR-R3」清明 \color{green}\text{P8478 「GLR-R3」清明} P8478 「 GLR-R3 」清明
看到乘积先拆成每个最后的台阶选一个上面的水滴。依次考虑初始状态每个台阶水滴去哪里并状压哪些台阶已经选了水滴,可以做到 O ( n 3 2 k ) O(n^32^k) O ( n 3 2 k ) 。显然我们得找个 O ( poly ( n ) 2 n − k ) O(\text{poly}(n)2^{n-k}) O ( poly ( n ) 2 n − k ) 的东西拼起来。注意到只有 n − k − 1 n-k-1 n − k − 1 个最终台阶的水滴来源不是一个前缀,对它们容斥之后每个台阶的水滴来源都是一个前缀,于是容易设计多项式复杂度的 DP。复杂度 O ( n 3 2 n − k ) O(n^32^{n-k}) O ( n 3 2 n − k ) ,拼起来是 O ( n 3 2 n 2 ) O(n^32^{\frac{n}{2}}) O ( n 3 2 2 n ) 。
CF2045K GCDDCG \color{green}\text{CF2045K GCDDCG} CF2045K GCDDCG
考虑下 i = 1 i=1 i = 1 咋求答案。那就是 ∑ x ∣ gcd ( A ) ∑ y ∣ gcd ( B ) μ ( x ) μ ( y ) \sum_{x \mid \text{gcd}(A)}\sum _{y \mid \text{gcd}(B)} \mu(x) \mu(y) ∑ x ∣ gcd ( A ) ∑ y ∣ gcd ( B ) μ ( x ) μ ( y ) 状物对吧。枚举完 x , y x,y x , y 之后答案会和 x , y , lcm ( x , y ) x,y,\text{lcm}(x,y) x , y , lcm ( x , y ) 有关,可以快速计算。打个表发现 lcm ( x , y ) ≤ n \text{lcm}(x,y) \le n lcm ( x , y ) ≤ n 的对数只有一千多万对(实际上据题解说好像有重磅结论是 O ( n log 2 n ) O(n \log^2n) O ( n log 2 n ) 的),于是对于这些数对暴力计算贡献,然后 lcm ( x , y ) > n \text{lcm}(x,y)>n lcm ( x , y ) > n 的推下式子对于 x , y x,y x , y 分别是独立的两堆东西乘起来,那就好算。对每个 i i i 跑上面那个算法是 ∑ i n i log 2 n i \sum_i\frac{n}{i}\log^2 \frac{n}{i} ∑ i i n log 2 i n 即 O ( n log 3 n ) O(n \log^3n) O ( n log 3 n ) 的,把不是 square-free 的数对剪枝掉跑得飞快。
P10175 「OICon-02」Subtree Value \color{red}\text{P10175 「OICon-02」Subtree Value} P10175 「 OICon-02 」 Subtree Value
枚举每个 p c p^c p c 做,最后合并答案。相当于每个点有个多项式 ( a i + x ) (a_i+x) ( a i + x ) ,记一个连通块的权值为里面所有点多项式的乘积。考虑对每种连通块大小求出该大小的所有连通块的权值之和,然后带入该连通块的大小求值即可。考虑插值求出多项式,注意到 x p c ‾ ≡ 0 ( m o d p c ) x^{\underline{pc}} \equiv 0 \pmod {p^c} x p c ≡ 0 ( mod p c ) ,于是这个多项式一定不超过 ( p c − 1 ) (pc-1) ( p c − 1 ) 次。复杂度 O ( n 2 U V ) O(n^2UV) O ( n 2 U V ) 。
P9157 「GLR-R4」夏至 \color{red}\text{P9157 「GLR-R4」夏至} P9157 「 GLR-R4 」夏至
设 F ( n , m ) = ∑ i = 1 m f ( n i ) F(n,m)=\sum_{i=1}^m f(ni) F ( n , m ) = ∑ i = 1 m f ( ni ) ,答案为 ∑ i = 1 n F ( i , m ) \sum_{i=1}^n F(i,m) ∑ i = 1 n F ( i , m ) 。计算 F ( n , m ) F(n,m) F ( n , m ) ,枚举 n n n 最大质因子 p c p^c p c 在 m m m 侧被选了几次,则 F ( n , m ) = ∑ i ≥ 0 ( F ( n p c , ⌊ m p i ⌋ ) − F ( n p c − 1 , ⌊ m p i + 1 ⌋ ) ) f ( p c + i ) F(n,m)=\sum_{i \ge 0} \left(F\left(\frac{n}{p^c},\left\lfloor\frac{m}{p^i}\right\rfloor\right)-F\left(\frac{n}{p^{c-1}},\left\lfloor\frac{m}{p^{i+1}}\right\rfloor\right)\right)f(p^{c+i}) F ( n , m ) = ∑ i ≥ 0 ( F ( p c n , ⌊ p i m ⌋ ) − F ( p c − 1 n , ⌊ p i + 1 m ⌋ ) ) f ( p c + i ) 。这里有一步小容斥,就是用至少 i i i 次的贡献减去至少 ( i + 1 ) (i+1) ( i + 1 ) 次的贡献,强制多钦定的那个 p p p 可以放到 n n n 那一侧,所以 c c c 就变成 ( c − 1 ) (c-1) ( c − 1 ) 。递归边界为 n = 1 n=1 n = 1 ,此时 PN 筛计算即可。这里递归的总转移数在本题数据范围下只有 2 × 10 7 2 \times 10^7 2 × 1 0 7 的样子。预处理 n × m ≤ 10 6 n \times m \le 10^6 n × m ≤ 1 0 6 的 F ( n , m ) F(n,m) F ( n , m ) 可以显著优化常数。
P8570 [JRKSJ R6] 牵连的世界 \color{red}\text{P8570 [JRKSJ R6] 牵连的世界} P8570 [JRKSJ R6] 牵连的世界
zak 科技。求 ∑ i ≤ n ∧ j ≤ m f ( i j ) \sum_{i \le n \land j \le m}f(ij) ∑ i ≤ n ∧ j ≤ m f ( ij ) 其中 f ( n ) f(n) f ( n ) 为积性函数。如果只算 gcd ( i , j ) = 1 \gcd(i,j)=1 g cd( i , j ) = 1 的 f ( i j ) = f ( i ) f ( j ) f(ij)=f(i)f(j) f ( ij ) = f ( i ) f ( j ) 之和,直接莫反容易 O ( n log log n ) O(n \log\log n) O ( n log log n ) 。考虑枚举 gcd \gcd g cd 为 d d d ,设 h ( n ) = f ( d 2 n ) f ( d 2 ) h(n)=\frac{f(d^2n)}{f(d^2)} h ( n ) = f ( d 2 ) f ( d 2 n ) ,则 h h h 为积性函数,且 f ( i j ) = h ( i ) h ( j ) f ( d 2 ) f(ij)=h(i)h(j)f(d^2) f ( ij ) = h ( i ) h ( j ) f ( d 2 ) ,于是可以用刚刚的做法。总复杂度 O ( n log n log log n ) O(n \log n \log \log n) O ( n log n log log n ) 。本题直接 f ( n ) = σ 0 ( n ) φ ( n ) f(n)=\sigma_0(n)\varphi(n) f ( n ) = σ 0 ( n ) φ ( n ) 就好了。
P6837 [IOI 2020] 数蘑菇 \color{red}\text{P6837 [IOI 2020] 数蘑菇} P6837 [IOI 2020] 数蘑菇
首先你会一个 O ( n ) O(\sqrt n) O ( n ) 的做法,就是先每次问两个直到得到 O ( n ) O(\sqrt n) O ( n ) 个同色蘑菇(不妨设是 A),然后你问 A,?,A,?,A,?,A \texttt{A,?,A,?,A,?,A} A,?,A,?,A,?,A 这样的东西就可以每次获取 O ( n ) O(\sqrt n) O ( n ) 个蘑菇里有多少个 A。然后你要卡常。OU 告诉我们,这里有这样一个 trick:考虑取小整数 k k k ,初始维护前 k k k 个蘑菇可能的所有情况(有 2 k 2^k 2 k 种),每次随机 K = 1000 K=1000 K = 1000 种询问,取最坏情况下情况数减少最多的一种。情况减少后尝试加入接下来的蘑菇,维护总情况数保持在 O ( 2 k ) O(2^k) O ( 2 k ) 级别。
想到折半就做完了。启示大概是单起点单终点求路径的形式很适合折半。
CF2048H Kevin and Strange Operation \color{red}\text{CF2048H Kevin and Strange Operation} CF2048H Kevin and Strange Operation
重新刻画操作:把所有 [ 1 , p ) [1,p) [ 1 , p ) 的 1 连续段向右延伸一格,然后删除开头。可以不管删除开头这个部分,最后如果操作了 i i i 次则只保留 ( n − i ) (n-i) ( n − i ) 位。延伸可以以 1 连续段为单位考虑,也就是选一个前缀的 1 连续段延伸一格。只需对每个 1 连续段被延伸的次数 DP。
P8519 [IOI 2021] 钥匙 \color{red}\text{P8519 [IOI 2021] 钥匙} P8519 [IOI 2021] 钥匙
如果从 u u u 出发最终能到达 v v v 的话,连一条有向边 ( u , v ) (u,v) ( u , v ) 。那么我们所求的答案一定在出度为 0 0 0 的 SCC 里。考虑对每个出度为 0 0 0 的 SCC 求一个点,如果能求出来的话,从这些点出发暴力遍历的复杂度是对的。怎么求呢,你发现只需维护一个每个点出度至多为 1 1 1 的生成森林,每次拉两个的根出来看一下有没有边,连不了之后所有根节点就是我们要的。但是这个太暴力了,我们考虑 Boruvka 的过程,每次从每棵树的根节点出发遍历,以这个树的大小的代价来获得它连向的外面的点或者直接把它标记为无出度 SCC 里的点。这样做一轮树的数量至少减半,于是是 O ( ( n + m ) log n ) O((n+m)\log n) O (( n + m ) log n ) 的。
CF1687D Cute number \color{green}\text{CF1687D Cute number} CF1687D Cute number
实际上相当于有一些区间,然后找一个最小的 x x x 使得 x + a i x+a_i x + a i 都在区间里。一个显然的观察是答案是 O ( V 2 ) O(V^2) O ( V 2 ) 的。枚举 a 1 + x a_1+x a 1 + x 在哪个区间,然后你注意到此时每个 a i a_i a i 最后只能到达至多一个确定的区间,每个 a i a_i a i 的贡献是把合法的 x x x 对某个范围取交。这样暴力做就是 O ( n V ) O(nV) O ( nV ) 。考虑优化,刚刚的过程实际上相当于枚举每个 a i a_i a i ,找到一个它对应的区间,考虑改成枚举区间并处理它对应的 a i a_i a i 的贡献。注意到如果 x + a 1 x+a_1 x + a 1 所在区间长度为 l l l 则只会枚举 O ( V l ) O(\frac{V}{l}) O ( l V ) 个区间,所以复杂度为调和级数的 O ( V log V ) O(V \log V) O ( V log V ) 。
[AGC045A] Xor Battle \color{green}\text{[AGC045A] Xor Battle} [AGC045A] Xor Battle
倒着做,维护一个集合 S S S 代表当且仅当走到这里的时候在集合 S S S 里会使得 0 0 0 获胜。发现 S S S 总是可以被一个线性基表示,做完了。
[AGC044E] Random Pawn \color{red}\text{[AGC044E] Random Pawn} [AGC044E] Random Pawn
环没有任何用,可以从最大值断环为链。b i = 0 b_i=0 b i = 0 的问题所有人都会做,见 P5155。有 b i b_i b i 的情况,记答案为 f i f_i f i ,就是 f i = max ( f i − 1 + f i + 1 2 − b i , a i ) f_i=\max\left(\frac{f_{i-1}+f_{i+1}}{2}-b_i,a_i\right) f i = max ( 2 f i − 1 + f i + 1 − b i , a i ) ,考虑设参数 c i c_i c i 使得 f i − c i = max ( ( f i − 1 − c i − 1 ) + ( f i + 1 − c i + 1 ) 2 , a i − c i ) f_i-c_i=\max\left(\frac{(f_{i-1}-c_{i-1})+(f_{i+1}-c_{i+1})}{2},a_i-c_i\right) f i − c i = max ( 2 ( f i − 1 − c i − 1 ) + ( f i + 1 − c i + 1 ) , a i − c i ) ,这样就归约到了 b i = 0 b_i=0 b i = 0 的问题。c i c_i c i 所有人都会算。
P6222 「P6156 简单题」加强版 \color{green}\text{P6222 「P6156 简单题」加强版} P6222 「 P6156 简单题」加强版
直接莫反就是
O ( n log log n + T n ) O(n \log \log n+T \sqrt n) O ( n log log n + T n ) 可以通过。瓶颈是求一个积性函数和
μ \mu μ 的卷积。实际上两个积性函数卷积是可以
O ( n ) O(n) O ( n ) 做的,做法是直接对结果函数线性筛。
P7486 「Stoi2031」彩虹 \color{green}\text{P7486 「Stoi2031」彩虹} P7486 「 Stoi2031 」彩虹
Gym103428C Assign or Multiply \color{red}\text{Gym103428C Assign or Multiply} Gym103428C Assign or Multiply
简单转化一下就变成了:循环卷积意义下 01 背包,对每个
i i i 判断是否存在方案。考虑 01 背包的转移过程,显然把 0 变成 1 只有
O ( m ) O(m) O ( m ) 次,问题是怎么找到这些转移。考虑定义函数
f ( l 1 , r 1 , l 2 , r 2 ) f(l_1,r_1,l_2,r_2) f ( l 1 , r 1 , l 2 , r 2 ) 代表用区间
[ l 1 , r 1 ] [l_1,r_1] [ l 1 , r 1 ] 的 1 更新
[ l 2 , r 2 ] [l_2,r_2] [ l 2 , r 2 ] ,用哈希判掉两个区间已经相同的情况,其它情况都暴力往下递归分治做。这样我们递归到叶子要么左区间是 1 右区间是 0,要么反之。前者是我们要找的,后者考虑模意义的性质,一个环上的 01 和 10 个数相等,所以势能是对的。复杂度
O ( m log 2 m ) O(m \log^2 m) O ( m log 2 m ) 。