Qingyu的博客

博客

Tags
None

Public NOIP Round #2 题解

2022-10-04 13:34:02 By Qingyu
  • 搬题人:
    • 就这:Y25t
    • 保序回归问题:Y25t
    • 恰钱:skip2004
    • 排序:Wu_Ren
    • 图同构:hehezhou
    • 找零:p_b_p_b
  • 组题人:p_b_p_b
  • 题解:p_b_p_b, Wu_Ren, Y25t, nantf

就这 (Div. 2 Only)

来源:

  • 2021-2022 ICPC Northern Eurasia - Belarus Regional Contest. Problem A. Constructiveforces
  • Кубок Трёх Четвертьфиналов 2021. Problem A. Constructiveforces

Tutorial by Y25t

其实只用保证每个长为 $m$ 的子串中恰好有 $k$ 个 1 就合法了,一种简单的构造是:

for(int i=0;i<n;i++) std::cout<<(i%m<k);

保序回归问题 (Div. 2 Only)

来源:

  • 2021-2022 ICPC Northern Eurasia - Belarus Regional Contest. Problem E. Positive Thinking
  • Кубок Трёх Четвертьфиналов 2021. Problem E. Positive Thinking

Tutorial by Y25t

当 $\prod y_i> 0$ 时,取 $x_i=y_i$,答案为 $0$。

当 $\prod y_i= 0$ 时,设 $\{y_i\}$ 中 $0$ 的个数为 $c$,那么至少要 $c$ 的代价才能使乘积非 $0$。而先把 $c-1$ 个 $0$ 变成 $1$,然后剩下那个 $0$ 根据情况变为 $1$ 或 $-1$ 即可取到这个下界。

当 $\prod y_i< 0$ 时,考虑 $\{y_i\}$ 中绝对值最小的位置,不妨设为 $j$。当 $y_j> 0$ 时将其变为 $-1$,否则将其变为 $1$,这样能使 $\prod y_i$ 反号,花费代价为 $|y_j|+1$,容易证明这是下界。

这些情况均可线性判断。

恰钱:(Div. 1 + Div. 2)

来源:

  • The 2022 ICPC Asia Regionals Online Contest (I)

Tutorial by p_b_p_b

如果你会数位 dp 那么可以直接往里套,显然是能做的。

否则,你也可以毛估估一下:

  • 当 $\text{ctz}(x)\le 5$ 时 $\text{ppc}(x)$ 也很小,这样只会有 $O((\log r)^4)$ 个合法的 $x$ 。
  • 否则这样的 $x$ 只有 $r/2^5$ 个,也不会太多,把合法的留下就更少了。

所以可以写个爆搜得到所有合法的 $x$ ,然后每次询问时二分。爆搜只需要 dfs+剪枝 即可。

最后,你也可以每次询问时枚举 $\text{ctz}(x)$ ,然后进行一些神秘贪心或调整,也可以通过此题。

排序:(Div. 1 + Div. 2)

来源:

  • Petrozavodsk Winter 2020. Day 8. Almost Algorithmic Contest. Problem C. StalinSort Algorithm

链接:https://qoj.ac/problem/1456

tutorial by Wu_Ren

考虑 dp,设 $f_i$ 为当前子序列结尾为 $a_i$ 并且保证最终子序列包含 $a_i$ 的情况下,当前子序列长度的最大值。

那么考虑 $f_i+1$ 贡献到 $f_j$ 的条件,设 $nx_i$ 为 $\min\{j\mid j>i\land a_j>a_i\}$,那么就是 $j\in[nx_i,nx_{nx_i})\land a_j>a_i$。

为了干掉 $a_j>a_i$ 这个条件,我们可以按 $a_i$ 从小到大枚举 $i$ 进行转移,这样就可以忽略这个条件。具体的,按 $a_i$ 从小到大枚举 $i$,用 $f_i$ 更新答案,然后用 $f_i+1$ 更新在 $[nx_i,nx_{nx_i})$ 中的 $f_j$。

注意,假如 $a_0=0$,那么 $f_i$ 的初值是 $[i\in[nx_0,nx_{nx_0})]$。

用线段树辅助转移,复杂度 $O(n\log n)$。

图同构:(Div. 1 Only)

来源:

  • 2021“MINIEYE杯”中国大学生算法设计超级联赛(6). Problem 1007. Power Station of Art
  • Petrozavodsk Summer 2021. Day 6. Xi'an JTU Contest 1, Grand Prix of Xi'an. Problem G. Power Station of Art
  • XXII Open Cup named after E.V. Pankratiev, Grand Prix of Xi'an. Problem G. Power Station of Art

链接:https://qoj.ac/problem/1869

Tutorial by nantf

对相邻两个点 $u,v$ 操作时,相当于将两点同时反色,然后交换颜色。于是可以看成每个点的颜色跟着点权形成的二元组在移动,从起点到终点如果经过了偶数条边(经过多次算多次)则最终颜色不变,否则最终颜色需要反色。

每个连通块独立,以下分别考虑每个连通块,有两种情况。

1. 该连通块为二分图

则无论如何移动,只要确定了每个二元组的起点和终点,则颜色是否被反色只与起点与终点是否在二分图的同一部有关。

分别考虑每种点权,则要求 $A$ 图和 $B$ 图的 左部黑点+右部红点 数量相等、右部黑点+左部红点 数量相等。这是一个必要条件。构造说明这也是充分条件。

任取这个连通块的一棵生成树,任取一个叶子,不妨设其在 $B$ 图中为左部黑点或右部红点,则任取 $A$ 图中一个点权相同的左部黑点或右部红点(由和相等一定存在),将其一路交换过来,以后的过程就可以在两张图中都忽略这个叶子。最后所有点都可以归位。

2. 该连通块不为二分图

也即该连通块一定存在奇环。

此时在确定每个二元组的起点和终点后,颜色是否被反色还不好确定。

再注意到,所有二元组经过的边数之和为偶数。则要求两图黑点奇偶性相同,红点奇偶性相同,且对于每种点权,两图的总点数相等。这是一个必要条件。构造说明这也是充分条件。

首先若整个连通块就是一个奇环,可以用下述的方法使得点权不变的前提下,相邻两个点 $x,y$ 的颜色反转。

  • 将 $x$ 上的二元组沿反方向交换一圈到 $y$ 点,然后将原本 $y$ 上的二元组沿反方向交换一圈到 $x$ 点。

那么先任意交换至点权对应,由黑点红点奇偶性不变,容易用该操作使得颜色也对应。

然后对于任意一个连通块,固定一个奇环,任取这个连通块的一棵生成树(要求奇环上至多一条边不属于该生成树),任取一个不在奇环上的叶子。任取 $A$ 图中一个点权相同的点一路交换过来,若仅沿树边交换会导致颜色不对,则交换到该叶子后再一路交换到奇环,绕奇环交换一圈,再原路返回,颜色就是正确的。最后只会剩下这个奇环的点没有归位,用上一种情况的做法即可。

直接按上述过程判断即可,时间复杂度 $O(n+m)$。

找零:(Div. 1 Only)

来源:

  • 京都大学プログラミングProgrammingコンテストContest 2021. Problem F. One Yen Coin
  • Petrozavodsk Winter 2022. Day 1. Kyoto U Contest 2. Problem F. Flatland Currency.
  • XXII Open Cup named after E.V. Pankratiev, Grand Prix of Kyoto. Flatland Currency.

链接:https://qoj.ac/problem/2544

Tutorial by p_b_p_b

可以发现,虽然纸币有不同面额,但我们其实只关心面额为 $1$ 的纸币数。剩余的钱具体是用哪些纸币表示出来,对后续操作没有影响。

因此也不难发现每次只会购买一个物品,不会出现打包购买的情况。

所以一个价格为 $a_i$ 的物品的价值就是 $5\lceil a_i/5\rceil-a_i$ ,我们需要做一个背包问题。但是价格实在是太高了。

注意到价值很小,所以可以把价值放进状态里。设 $dp_{i,j}$ 表示考虑了前 $i$ 个物品,获得的价值为 $j$ ,所需的最小代价,这样就可以把复杂度优化到 $O(n^2)$ 。

然后有多种继续优化的方法:

  • 注意到如果价值相同,那么一定是按价格从小到大选。所以可以设 $dp_{i,j}$ 表示考虑了所有价值 $\le i$ 的物品,获得的价值为 $j$ ,所需的最小代价,然后利用决策单调性在 $O(n\log n)$ 的时间内从 $dp_i$ 转移到 $dp_{i+1}$ 。
  • 注意到价值的 $\text{lcm}$ 是 $12$ ,所以可以把每种价值的物品分别先打包成价值为 $12$ 的包裹,然后按照价格从小到大选包裹。这样的一个问题是最优解的价值并不一定是 $12$ 的倍数,但是可以枚举价值为 $1,2,3,4$ 的物品选的个数模 $12,6,4,3$ 的值,然后先把这些物品选掉之后再贪心即可。
  • 放弃分析,直接先按照性价比排序贪心选,然后在每种价值物品的边界附近进行小背包。大概和前一种是等价的。

Public Easy Round #3 题解

2022-09-22 16:44:28 By Qingyu
  • 搬题人:
    • DNA 匹配 2:Qingyu
    • 情报传递 3:Qingyu
    • 别急 2:Qingyu
    • 旅程:flower
    • 染色:Qingyu
    • 运算符 2:feecle6418
    • 匹配求和:Qingyu
  • 组题人:Qingyu
  • 验题人:feecle6418, flower, gyh20, test12345
    UOJ 缺投!

DNA 匹配 2(50 Points)

来源:

  • infO(1) Cup 2017 National Round. Problem 2, DNA

链接:https://qoj.ac/contest/998/problem/4713

算法 1

题目好难啊,不太会做,干脆输出随机数吧!

期望得分 $1 \sim 2$ 分。

算法 2

我们接着输出随机数,由于是 bitand,所以我们考虑随机的时候让每个数的 popcount 大一些,例如要求每个数 popcount 至少为 $14$。

期望得分 $10 \sim 30$ 分。

算法 3

考虑将 $2000$ 个数分成两组 $A, B$,每组包含 $1000$ 个数。将第一组的二进制表示下 $0 \sim 9$ 位钦定为 $1$,$10 \sim 19$ 位设为随机数。将第一组的二进制表示下 $0 \sim 9$ 位设为随机数,$10 \sim 19$ 位钦定为 $1$。并假设任意两个数两两不同。

此时,注意到任取一对 $x \in A, y\in B$,$x \operatorname{and} y$ 恰好包含了 $y$ 的前 $10$ 位与 $x$ 的后 $10$ 位,这至少包含了 $1000\times 1000 = 10^6$ 种不同的结果。

期望得分 $50$ 分(满分)。

情报传递 3(50 Points)

来源:

  • ByteDance-Moscow Workshops Camp 2022. Shuffle Contest. Problem M, Multiple Communications

链接:https://qoj.ac/contest/997/problem/4675

算法 1

题目好难啊,不太会做,那就干脆把所有数都发过去吧!

需要 $NL$ 个 bit,可以通过子任务 1,获得 $5$ 分。

算法 2

如果 $x, y$ 均均匀独立随机生成,那么其前 $\ell$ 位相等的概率为 $2^{-\ell}$。因此,对于子任务 $3$,在数据随机的情形下,我们可以给每个串直接截取前 $30$ 位发送过去,并在询问时只使用 $C$ 的前 $30$ 位。

需要使用 $30N$ 个 bit,可以通过子任务 1 与子任务 3,获得 $10$ 分。

算法 3

算法 2 存在的问题是,我们可以刻意钦定一些位,使得每个串在这些位上均相等。为了避免攻击,我们可以给每个位 $i$ 附上一个 $[0,2^{30})$ 内的随机权值 $w_i$。根据 Schwartz–Zippel lemma,发生碰撞的概率即为 $\Pr[P(r_1,r_2,\ldots,r_n)=0]\leq\frac{d}{|S|}$。

需要使用 $30N$ 个 bit,期望得分 $50$ 分(满分)。

别急 2(75 Points)

来源:

  • ByteDance-Moscow Workshops Camp 2022. Shuffle Contest. Problem B, Broken Connection

链接:https://qoj.ac/contest/997/problem/4664

观察

注意到我们发送过去后顺序会被随机打乱,因此我们可以认为我们只能传递每种数的数量。

问题可以转化为我们可以发送 $10$ 个非负整数变量 $x_0,x_1,\cdots, x_9$,且需要保证 $\sum_{i=0}^9 x_i \le L$。

算法 1

注意到我们要传递一个 $10$ 位 $10$ 进制数,我们不妨考虑用 $x_i$ 来表示第 $i+1$ 位的值。这样在最坏情况下需要使用长为 $100$ 的字符串,得分 $7.5$ 分。

在此基础上可以进行一些常数优化,例如给每一位随机一个排列 $p_{0\cdots 9}$,转而使用 $p_i$ 来表示,这样期望情况下每一位只会用到长为一半的字符串,可以获得更多的分数。

算法 2

注意到对于方程 $x_1+\cdots+x_n = m$,我们可以使用隔板法来计数其非负整数解的数量 $f(n,m) = \binom{m+n-1}{n-1}$。因此,我们可以快速的求出一个局面的字典序。注意到当 $L=50$ 时,$\binom{50+10-1}{10-1} = 12565671261 > 10^{10}$,因此我们直接使用解的字典序来编码 $X$ 即可。

期望得分 $75$ 分(满分)。

旅程(75 Points)

来源:

  • Natjecanje timova studenata informatičara hrvatskih sveučilišta 2012. Problem G. Restorani

链接:https://qoj.ac/contest/433/problem/4852

算法 1

可以把题意中 $u$ 对 $v$ 喜欢,建成 $u$ 到 $v$ 的有向边。那么 $u$ 推荐 $v$ 就等价于,可以从 $u$ 走到 $v$。

先缩点后,对于每个scc考虑决策。

  1. 不经过这个 scc,代价是 0。
  2. 经过 $k$ 个此 scc 的点,其中 $1$ 个点的代价 $y_u$,剩下 $k-1$ 个点的代价是 $x_u$。

因此考虑预处理 $f_{u,i}$ 表示在第 $u$ 个 scc 经过 $i$ 个点的最代价。

令 $g_{u,i}$ 表示从第 $u$ 个 scc 开始走,经过 $i$ 个点的最小代价,转移是枚举 $u$ 的出边,和 $u$ 里走过了多少点,时间复杂度 $O(n^3)$

染色(75 Points)

来源:

本题修改自 Hong Kong Olympiad in Informatics 2014 Senior Group(香港電腦奧林匹克 2014 高級組)中的 Dividing the Cities(城市分配)一题。

算法 1

题目好难啊,不太会做,直接把整个方案给发送过去吧。

每个颜色需要占用 $3$ 个 bit,共需 $3N$ 个 bit,期望得分 $2$ 分。

算法 2A

如果 Bob 自力更生,自己寻找染色方案,那么是非常困难的。但是对一张图 $2$ - 染色非常简单:我们只需要 DFS 一遍即可。

我们不妨将颜色两两配对,对于颜色 $c$ 我们发送颜色 $\left\lfloor c/2\right \rfloor$。此时,我们需要将每一种颜色 $c'$,区分为 $2c'$ 与 $2c'+1$。这相当于我们要将这种颜色的点进行 $2$ - 染色,我们只需要 DFS 整张图即可线性完成。

这样,每个颜色只需要占用 $2$ 个 bit,共需 $2N$ 个 bit,期望得分 $24.85$ 分。

算法 2B

我们考虑另一个角度。如果这张图中,某个点的度数小于 $8$,那么我们可以直接删去这个点:将其余部分的染色方案复原后,他至多只有 $7$ 个邻居,因此总有一种颜色它可以直接使用。

这样,我们可以不断地删去图中度数小于 $8$ 的点,直到所有点的度数都至少为 $8$。由于一条边至多对度数之和贡献 $2$,因此剩余的点数不可能超过 $M/4$ 个。

这样,我们只需要发送 $M/4$ 个点的信息,共需 $3M/4$ 个 bit,期望得分 $30.92$ 分。

算法 3

同时使用算法 2A 与算法 2B,共需 $M/2$ 个 bit,期望得分 $75$ 分(满分)。

运算符 2(125 Points)

来源:

  • Petrozavodsk Winter 2021. Day 8. Belarusian SU Contest, Yandex Cup. Problem A. Belarusian State University
  • XXI Open Cup named after E.V. Pankratiev, Grand Prix of Belarus. Problem A. Belarusian State University

链接:https://qoj.ac/contest/536/problem/1083

算法 1

可以发现,二元 01 运算一共只有以下几种:

  • 恒 0 / 恒 1。这时可以通过重新对下标赋值,将其转为 AND 运算。
  • $f(x,y)=x$ 或 $f(x,y)=y$,或 $f(x,y)$ 等于 $x$ 或 $y$ 取反。这时可以通过重新对无关一边的下标赋值 1,将其转为 AND 运算。
  • 等价于,或把 $x$ 取反后等价,或把 $y$ 取反后等价,或均取反后等价 AND/XOR。

进行适当操作后,直接在每位上分别运用通常的 AND/XOR 卷积的处理方式即可。可以证明,AND 与 XOR 运算在每一位上不会互相干扰。

时间复杂度 $O(2^nn)$。

匹配求和(200 Points)

来源:

  • Petrozavodsk Winter 2020. Day 9. Yuhao Du Contest 7. Problem F. Fast as Ryser
  • XX Open Cup named after E.V. Pankratiev, Grand Prix of Zhejiang. Problem F. Fast as Ryser

链接:https://qoj.ac/contest/449/problem/2068

算法 1

设 $E_0 = \{ (1, 2), (3, 4), \cdots \}$,则注意到对任意 $E' \subseteq E$,$E'$ 是匹配当且仅当 $E' \cup E_0$ 是若干环与链的并。

image-per-3.jpg

注意到由于 $2i-1$ 与 $2i$ 必须在同一个集合内,因此集合总数只有 $O(2^{n/2})$ 种。因此我们可以在 $O(2^{n/2} \cdot n^2)$ 的时间复杂度内计算出对所有 $S$ 将其划分成环/链的方案数。例如,对于链,我们可以记 $dp[mask][i]$ 表示已经经过的 block 的集合为 $mask$,现在位于点 $i$ 的贡献之和。对于环,我们可以直接枚举最大的点当作环的起点,由于 $\sum_{i\le n} 2^i = 2^{n+1}-1$,因此复杂度仍为 $O(2^{n/2} \cdot n^2)$。

划分完成后,我们可以使用 SOS DP(时间复杂度 $O(n \cdot 3^{n/2})$)或子集 exp(时间复杂度 $O(n^2 \cdot 2^{n/2})$)来计算最终将图划分成若干环/链的方案数。

总的时间复杂度为 $O(n \cdot 3^{n/2})$ 或 $O(n^2 \cdot 2^{n/2})$。由于常数上的差异,两种算法实际上均可通过。

UOJ 缺投!

Public Easy Round #3 公告

2022-09-19 22:47:41 By Qingyu

提示:根据验题人的反馈,我们删去了一道题目并调整了分数分布。

Public Easy Round #3 将在 2022 年 9 月 25 日 08:00 举行!比赛将进行 5 小时,共 7 道题,OI 赛制。

在四个月后,又一场 PER 与大家见面了。与此前不同的是,我们调整了 Easy Round 的难度,增加了若干道签到题。题目的难度分布在 NOIP T1 至省选 T2,欢迎所有水平的选手来参加!

本次比赛中可能会包含若干道提交答案题、交互题与通信题。如果你不熟悉这些类型的题目,你可以使用 PTR #1、PER #1、PER #2 与 PR #6 中的题目来作为练习。

特别地,本场比赛每道题目的权重不同。题目的分数分布为 $50 + 50 + 75 + 75 + 75 + 125 + 200$,其中每道题目都可能包含一个或多个子任务,每个子任务中可能会有不同的评分方式。

本场比赛的组题人为 Qingyu,搬题人为 Qingyu, flower, feecle6418, Wu_Ren,验题人待定。

赛后会公开原题链接和题解链接。

特别提醒:本次比赛的题目均为原题,但为了比赛的公平性,请勿在比赛时尝试查找原题地址。如不幸见过原题,请向管理员报告。

Public NOIP Round #1 题解

2022-09-10 21:22:33 By Qingyu
  • 搬题人:
    • 一维围棋:Wu_Ren
    • 斜二等轴测图:Wu_Ren
    • 盒子里的糖果:hehezhou
    • 冲塔:p_b_p_b
    • 波特分组:feecle6418
    • 别急:Y25t
  • 组题人:p_b_p_b
  • 验题人:syzf2222, Zeardoe, Dualqwq, yllcm
  • 题解:hehezhou, Wu_Ren, p_b_p_b, Y25t

一维围棋 (Div. 2 Only)

来源:

  • ACM-ICPC Japan Alumni Group Summer Camp 2019. Problem A, AiGo
  • Petrozavodsk Summer 2020. Day 5: JAG Summer+ Opening Contest. Problem A, AiGo

QOJ 链接:https://qoj.ac/problem/1335

tutorial by Wu_Ren

枚举哪个位置去放棋子,首先如果上面已经有棋子就不能放,然后向左向右如果都是连续一段白再接一段黑,那么也不能放,否则一定能放。放了之后向左向右分别扫一遍即可知道占领了多少黑棋。

复杂度 $O(n)$ 或 $O(n^2)$。

斜二等轴测图 (Div. 1 + Div. 2)

来源:

  • 2018 Multi-University Training Contest 3. Problem B, Visual Cube
  • Petrozavodsk Summer 2020. Day 3: Songyang Chen Contest 3. Problem B, Visual Cube

QOJ 链接:https://qoj.ac/problem/1266

tutorial by Wu_Ren

按照题意模拟即可,复杂度 $O(T(a+b)(b+c))$。

盒子里的糖果 (Div. 2 Only)

来源:

  • Petrozavodsk Summer 2021. Day 4: Shanghai ICPC Camp 2021 Onsite Day 1 by PKU. Problem F, Interval Shuffle

QOJ 链接:https://qoj.ac/problem/1848

tutorial by hehezhou

算法一

令 $dp_{i,j}$ 表示 $i$ 次操作后,$a_j$ 的最大值。

那么有: $$\begin{cases}dp_{i,j}=dp_{i-1,j}&j\in[1,l_i)\bigcup(r_i,n]\\ dp_{i,j}=\max(dp_{i-1,j}+1,\max_{k\in [l_i,r_i]}dp_{i-1,k})&j\in[l_i,r_i]\end{cases}$$

即只需考虑 $i-1$ 步时的最大值即可推出 $i$ 步后的最大值。构造某位的最大值只需按照 dp 转移式逆推即可。

时间复杂度 $O(n^2)$。

算法二

考虑用线段树优化上述过程:

  1. 计算 $\max_{k\in [l_i,r_i]}dp_{k}$ 即为一次查询区间最大值。
  2. 更新 $dp$ 值可以表示为一次区间加和一次区间取 $\max$。

这是一个经典线段树问题,可以在 $O(n\log n)$ 的时间复杂度内解决。

冲塔 (Div. 1 + Div. 2)

来源:

  • National Olympiad in Informatics 2022. Problem 3, Towers

QOJ 链接:https://qoj.ac/problem/3873

tutorial by p_b_p_b

先不管“每列只能冲至多两个塔”的限制,直接先把每行最左和最右的塔都冲掉。

这时候当然可能会出现某一列超过两个塔了。但是往好处想:如果超过两个塔,是不是说明中间那个塔就不需要冲了呢?

因此可以每次找到最靠右的一列,使得这一列有超过两个塔,然后把中间的那些塔全都往左移动一位。

不难发现每次这样操作之后仍然满足每个塔都被覆盖,并且 $O(n)$ 次操作之后就不会存在冲了超过两个塔的列了。

用 set 维护,复杂度 $O(n\log n)$ 。

波特分组 (Div. 1 Only)

来源:

  • Petrozavodsk Winter 2020. Day 7: Gennady Korotkevich Contest 5. Problem F, Flip
  • XX Open Cup named after E.V. Pankratiev, Grand Prix of Gomel. Problem F, Flip

QOJ 链接:https://qoj.ac/problem/1427

tutorial by feecle6418

设 $S=\sum k$。

算法一

直接枚举每枚硬币哪面朝上,时间复杂度 $O(q2^{2n})$,可以通过第一个子任务,期望得分 $9$。

算法二

考虑先枚举每一种情况,用子集和变换预处理每种输入哪些会有贡献,时间复杂度 $O(2^{2n}n+S)$,可以通过前两个子任务,期望得分 $25$。

此外,可能存在一些高复杂度算法,可以通过前三个子任务。

算法三

首先,给定一种分组状态,它出现的概率是多少?设最后一个分到 A 组的人编号为 $i_A$,最后一个分到 B 组的人编号为 $i_B$,则概率为 $2^{-\min(i_A,i_B)}$。

对于每组询问,不妨假设全分在 A 组,枚举 $\min(i_A,i_B)=p$ 的值,计算分组方案数:

  • $p=b_k$,此时分组方案数为 $\binom{b_k-k}{n-k}$。
  • $p$ 位置分在 B 组,不妨设 $b_i < p < b_{i+1}$,则分组方案数为 $\binom{p-i-1}{n-1}$。对于固定的 $i$,$p-i-1$ 构成区间,恰当预处理前缀和可以 $O(1)$ 求出。
  • $p>b_k$ 且 $p$ 位置在 A 组,则分组方案数为 $\binom{p-k-1}{n-k-1}$。对于每种出现的 $k$,分别 $O(n)$ 预处理该式与概率的乘积的后缀和即可。

因为不同的 $k$ 只有 $\sqrt S$ 个,所以时间复杂度 $O(n\sqrt S+S)$,期望得分 $100$。注意边界。

本题也存在线性做法。

别急 (Div. 1 Only)

来源:

  • XXII Open All-Siberian Programming Contest named after I.V. Pottosin Final tour, II day. Problem 11: Captivating process
  • XXII Open Cup named after E.V. Pankratiev, Grand Prix of Siberia. Problem 11: Captivating process

QOJ 链接:https://qoj.ac/problem/4758

tutorial by Y25t

建两张有向图 $F,G$,对所有 $1\le i\le n$ 在 $F$ 中连有向边 $(i,f_i)$,在 $G$ 中连边 $(i,g_i)$。那么它们分别形成基环内向森林。

对于一个点 $u$ ,若它能沿着 $F$(或 $G$)中唯一出边走若干步能回到 $u$,则称它为 $F$(或 $G$)中的环点,否则称它为 $F$(或 $G$)中的树点。定义 $dep^F_u$ 为在 $F$ 中 $u$ 第一次走到环点所需步数。若 $u$ 在 $F$ 中是环点,则 $dep^F_u=0$,同时定义 $l^F_u$ 为 $u$ 所在环的长度,$d^F_u$ 为 $u$ 在其所在环上的编号(满足 $0\le d^F_u< l^F_u$ 且 $d^F_{f_u}\equiv d^F_{u}+1\pmod{l^F_u}$)。类似地定义 $dep^G,l^G,d^G$。

对于一块石板 $(x,y)$,不妨设 $dep^F_x\le dep^G_y$。考虑将时间分为 $[0,dep^F_x),[dep^F_x,dep^G_y),[dep^G_y,+\infty)$ 三段,分别判断是否会裂开。

$[0,dep^F_x)$

在这段时间里,$x$ 为在 $F$ 中的树点,$y$ 为在 $G$ 中的树点。

该石板会在这段时间中裂开,当且仅当存在点 $u$ 使得以下三个条件同时满足:

  • $dep^F_x-dep^F_u=dep^G_y-dep^G_u$,即 $dep^F_u-dep^G_u=dep^F_x-dep^G_y$。
  • 在 $F$ 中 $u$ 是树点,且为 $x$ 的祖先。
  • 在 $G$ 中 $u$ 是树点,且为 $y$ 的祖先。

于是将询问离线后在 $G$ 的树部分进行 dfs。用 std::set 或动态开点线段树维护 $2n$ 个线段集合 $S_i(-n\le i\le n)$。在进入一个点 $u$ 时,在 $S_{dep^F_u-dep^G_u}$ 中插入线段 $[dfn^F_u,dfn^F_u+sz^F_u-1]$(其中 $dfn^F,sz^F$ 为在 $F$ 中的 dfs 序和子树大小),回溯时撤销。对于询问 $(x,y)$,在进入 $y$ 后判断 $S_{dep^F_x-dep^G_y}$ 中是否有线段覆盖了 $dfn^F_x$ 即可。

该算法加一些简单特判后可通过子任务 7。

$[dep^F_x,dep^G_y)$

在这段时间里,$x$ 为在 $F$ 中的环点,$y$ 为在 $G$ 中的树点。

该石板会在这段时间中裂开,当且仅当存在点 $u$ 使得以下三个条件同时满足:

  • $d^F_u-d^F_x\equiv dep^G_y-dep^G_u\pmod{l^F_u}$ 即 $d^F_u+dep^G_u\equiv d^F_x+dep^G_y\pmod{l^F_u}$。
  • 在 $F$ 中 $u$ 是环点,且与 $x$ 在同一环中。
  • 在 $G$ 中 $u$ 是树点,且为 $y$ 的祖先。

于是可以用类似的 dfs 进行求解。

该算法加一些简单特判后可通过子任务 6。

$[dep^G_y,+\infty)$

在这段时间里,$x$ 为在 $F$ 中的环点,$y$ 为在 $G$ 中的环点。

该石板会在这段时间中裂开,当且仅当存在点 $u$ 使得以下三个条件同时满足:

  • $d^F_u-d^F_x\equiv d^G_u-d^G_y\pmod{\gcd(l^F_u,l^G_u)}$
  • 在 $F$ 中 $u$ 是环点,且与 $x$ 在同一环中。
  • 在 $G$ 中 $u$ 是环点,且与 $y$ 在同一环中。

std::set 维护三元组即可简单判断。

该算法可直接通过子任务 5。

结合以上三个算法即可通过本题。

Public NOIP Round #1 公告

2022-09-05 19:53:49 By Qingyu

Public NOIP Round #1 将在 2022 年 9 月 10 日 14:00 举行!

这是 Public Judge 举办的第一场 NOIP 系列模拟赛,欢迎捧场!

比赛将分为普及组和提高组,普及组进行 3.5 小时,提高组进行 4 小时。普及和提高分别有 4 道题,OI 赛制,其中普及组和提高组有两题相同。 本次比赛的题目难度约为 CSP J/S,所有题目都有部分分。 本次模拟赛的组题人为 p_b_p_b ,搬题人为 Y25t, feecle6418, Qingyu, Wu_Ren, hehezhou, p_b_p_b ,验题人为 syzf2222, Zeardoe, Dualqwq, yllcm。 赛后会公开原题链接和题解链接。

特别提醒:本次比赛的题目均为原题,但为了比赛的公平性,请勿在比赛时尝试查找原题地址。如不幸见过原题,请向管理员报告。

Solution Sketch

2022-07-13 23:12:45 By Qingyu

A. Add One

考虑把 $+1$ 看成 $xor a$ 操作,可以发现 $a$ 只可能是 $2^k-1 (k \ge 1)$。因此考虑枚举 $a$ 判断是造出来 $???????01111$ 的形式,可以从低位到高位建线性基,每次从低位到高位贪心的xor,时间复杂度 $O(n \log w)$

B. Beautiful Sum

$$ \sum_{i=1}^n (\mu(i)\mu(i+k))^2 \\ = \sum_{i=1}^n \sum_{d^2 | i} \mu(d) \sum_{e^2 | i+k}\mu(e) \\ = \sum_{d = 1}^{\sqrt n}\mu(d)\sum_{e=1}^{\sqrt n} \sum_{i=1}^n [d^2 | i \land e^2 |i + k] $$

最后一部分等价于 $ye^2-xd^2=k, 1 \le xd^2 \le n$ 的解的数量。可以利用 exgcd 计算。 同时也可以找到所有 $xd^2, ye^2$,用双指针计算所有相差为 $k$ 的数量。 因此可以对于 $d^2,e^2>B$ 的数对采用做法2,时间复杂度为 $\sum_{i=B}^{\sqrt{n}} \frac{n}{i^2} = \frac{n}{B}$,其它采用第一个做时间复杂度为 $O(B\sqrt{n} \log n)$, 令 $B = \frac{n^{1/4}}{\log^{1/2}} n$,时间复杂度为 $O(n^{3/4}\log^{1/2} n)$。

C. Counting Sequence

令 $B = \sqrt{2n}$。 当 $a_1 \le B$ 时$\max a_i$ 是 $O(\sqrt{n})$ 的,因此可以$f_{i,j}$ 表示和为 $i$ 上一个数字为 $j$。 当 $a_1 > B$ 时不需要考虑 $a_i>0$ 的限制,因此可以 $g_{i,j}$ 表示 $i$ 个数字,$\sum_{k=1}^i a_k-i\times a_1 = j$,考虑枚举 $a_1,a_2$ 的关系转移。 时间复杂度是 $O(n\sqrt{n})$。

E. Exciting Travel

原问题等价于,用 $p_i,p_{i+1}$ 的路径上的点换答案$+1$。 考虑建立虚树,令 $f_u$ 表示 $u$ 的子树的答案。对于$l_i = lca(p_i, p_{i+1})$,在$lca$ 处枚举是否选择这条路径。考虑所有的转移类似于$\sum_{u \in path(p_i,p_{i+1}), v\not \in path(p_i,p_{i+1})} f_v + 1$。考虑令 $g_u = \sum_{v} f_v-f_u$,这个式子可以写成$g$ 的链和加上常数的形式,因此在$dp$的过程直接维护$g$的前缀和即可。

F. Flower's Land

考虑点分治,分治重心为 $rt$,计算必须包含 $rt,u$ 的大小为 $k$ 的连通块的最大权值。 令 $f_{i,j}$ 表示先序遍历为 $[i,n]$ 内部的点选了 $j$ 个并且满足不存在 $u,fa_u$ 的 dfn序在$[i,n]$ 并且 $u$ 选了,$fa_u$ 没选,枚举是否选 $u$ 以此决定是否跳过 $u$ 的子树即可。类似的令 $g_{i,j}$ 表示后序遍历 $[1,n]$ 的选 $j$ 的权值。$O(k)$ 合并两个背包的某个点即可。 点分治的当前区域大小少于$k$ 的时候剪枝,复杂度为 $O(nk\log {\frac{n}{k}})$

G. Games

令 $f_{u,i,0/1}$ 表示 $u$ 的子树,$a_u = i$,是否有子树内的点比$a_u$ 大,利用前缀和转移即可。 类似的,令 $g_{u,i,0/1}$ 表示 $u$ 的子树补的答案。通过换根 dp 转移即可。时间复杂度 $O(nm+q)$。

I. Inverse Line Graph

考虑问题转化为,给新图每个点赋两个权值,代表的含义是原图的端点,因此需要保证任意一个颜色的导出子图是完全图,并且每条边在恰好一个完全图里,称边被颜色覆盖为边在这个颜色的导出子图里。 我们随便选一个点 $u$ 考虑把 $u$ 的出边划分成两个集合,分别代表两个颜色。不妨设 $u$ 的出度为 $S$,两种颜色的集合分别为 $S_1, S_2$。 假设我们得到了正确的划分,对于 $S$ 中的每个点,已经使用了一种颜色,对于剩下的没有被覆盖的边,必须成为一个新的完全图,因此可以递归处理。 设$x\in S_1, y_1,y_2 \in S_2$ 且 $(x,y_1),(x,y_2)$,那么 $x,y_1$ 和 $x,y_2$ 必须染一个颜色,但是 $y_1,y_2$ 的边已经被覆盖,因此无解。因此 $S_1,S_2$ 之间是一个匹配。 任选一个 $p \in S$,令 $S_1= \{p\}, S_2 = S - S_1$,并且检验一遍。 那么一定存在$p,q \in S_1, (p,q)$。假设我们有 $p,q \in S_1$ 的初始条件,那么对于$x \in S$,若与$p,q$ 均有连边,必须在$S_1$ 里,否则在$S_2$ 里。经过上述过程,假设 $p,q,t\in S$,那么 $p,q$ 在一个集合里与 $p,t$ 在一个集合里的初始条件是等价。对于 $t\in S_2,(p,t)$,通过上述方法同样检验一遍。如果仍然不满足意味着, $p,q$ 不在一个集合, $p,t$ 不在一个集合,因为 $t \in S_2$,所以 $t,p$ 没有边因此 $t,q$ 不在一个集合,于是无解。 因此可以转化为最多 $3$ 次检验,每次时间复杂度 $O(n+m)$,总时间复杂度$O(\sum n+\sum m)$。

J. Just Another Number Theory Problem

考虑计算 $s_i$ 表示有多少对相邻的差为 $i$,并且依次加入质数。 因为是任意两个数字互质,因此是均匀分布的,所以有转移$s_i:=(p - i + 1) s_i + 2 \sum_{j > i} s_j$,利用后缀优化即可。

N. No!

只用关心 $h$ 为前缀最大值的位置,因此对强按照从大到小排序后,令 $f_i$ 表示必须选第 $i$ 面强,不考虑第 $i$ 会倒的答案。那么有$f_i = \max_{j=1}^{i-1} \min(f_j, \frac{h_j-h_i}{a_j})$,后半部分可以看成一个平移的反比例函数和一个值域上限。因为对于两个 $j_1,j_2$ 对后续的贡献不考虑上限只有一个交点,因此考虑用类似于斜率优化的方式维护即可。如果使用基数排序和gcd技巧可以做到 $O(n + m + q)$。

Blog System

2022-04-03 11:28:42 By Qingyu

it works.

PA 2021 简单题的简要题解

2022-01-01 00:28:59 By Qingyu

前几天做了做今年 PA 的题. 因为难题都不会做,所以把简单题的题解写了:

Round 1

[C] Koszulki

签到题. 排序以后找到对应位置把相等的元素都取了即可.

[B] Oranżada

注意到我们肯定是取前 $k$ 个不同的元素交换过去, 因为取后面的元素的话交换序列就会有交叉, 一定是不优的.

[A] Od deski do deski

首先注意到序列可以删除当且仅当序列可以划分成若干个长度 $\geq 2$ 的子序列使得端点元素的值相同.

注意若到此时的序列是 $S$, 假设我们当前可以通过在 $S$ 后添加元素 $x$ 使得序列变得合法, 那么 $S+x$ 也可以通过添加 $x$ 使得序列变得合法. 所以, 我们不妨设 $dp_{i,0/1,j}$ 表示考虑到 $i$, 当前序列合法/不合法, 最后有 $j$ 个 $x$ 使得 $S+x$ 变得合法. 转移为:

  1. 若当前序列合法, 则如果我们添加了 $j$ 个 $x$ 中的一个, 则转移到一个合法的序列; 否则, 我们转移到一个不合法的序列. 如果我们此时在后面接着接上上述 $j$ 个 $x$, 那么我们其实可以无视最后一个元素, 合法的选法仍然合法. 同时, 我们也可以选择直接接上一个上一次我们选的元素, 所以总的选法有 $j+1$ 个
    • $dp_{i,j,0} \cdot j \mapsto dp_{i+1,j,0}$
    • $dp_{i,j,0} \cdot (n-j) \mapsto dp_{i+1,j+1,1}$
  2. 若当前序列不合法, 则我们如果接了一个合法的序列, 显然会转移到一个合法的序列, 同时根据上文我们也有接下来合法选法有 $j$ 种. 否则, 相当于我们接了个没用的元素过来, 选法是不变的.
    • $dp_{i,j,1} \cdot j \mapsto dp_{i+1,j,0}$
    • $dp_{i,j,1} \cdot (n-j) \mapsto dp_{i+1,j+1,1}$

因此直接 DP 即可. 时间复杂度为 $O(n^2)$

Round 2

[C] Zakłócenia

我们暴力预处理一下最小和最大的popcount是多少, 然后只要保证填完以后仍然在取值范围里即可. 时间复杂度为 $O(n \log |\Sigma|)$

[B] Pandemia

首先, 如果我们不考虑第一段和最后一段的话, 那么相当于是这样一个问题:

有 $n$ 个数, 第 $i$ 个数为 $x_i$. 每天白天你可以选择一个数并获得它的大小的收益, 随后每天晚上每个数的大小减 $2$. 问你可能的最大收益是多少.

容易发现我们直接把 $x_i$ 从大到小排序后贪心选择是最优的. 这是因为我们相当于是每天除了已经被选走和已经小于 $0$ 的数以外, 每个数使得收益减了 $2$. 由于较小的数更快小于零, 所以我们留着它们是最优的.

对于有开头和结尾的情况, 我们可以将除了开头和结尾以外的每个连续段 $x$ 看成 $2$ 个 $x/2$, 这样一定是最优的. 因为我们注意到一个长度为 $l$ 的段, 我们是不可能堵住了一边, 然后另一边跨过了中线的 - 当我们堵住一部分的时候, 我们肯定会立刻堵住另一部分, 否则堵住左边没有意义.

[A] Poborcy podatkowi

我们考虑一个暴力 dp. 设 $f[x][i]$ 表示考虑以 $x$ 为根的子树, 且它往上贡献一个长为 $i$ 的链, 最大收益是多少. 转移时, 我们做一个背包, 记 $g[b][c][d]$ 表示选了 $b$ 个 $1$, $c$ 个 $2$, $d$ 个 $3$ 的最大收益, 那么我们可以获得一个高达 $O(n^4)$ 的做法.

注意到我们一定是1和3匹配,2和自己匹配. 所以我们只需要知道 $b-d$ 的值 $\Delta$ 和 $c$ 的奇偶性 $o$, 这样背包数组就是 $g[\Delta][0/1]$, 总的时间复杂度是 $O(n^2)$ 的.

注意到我们其实只需要知道 $g[-1/0/1][0/1]$ 的值, 而我们知道, 对于一个有 $n$ 个 +1 和 $n$ 个 -1 的序列, 将其 shuffle 后, 前缀和绝对值的最大值是 $O(\sqrt n)$ 级别的. 所以我们直接 shuffle 一下所有儿子, 然后第二维强制要求过程中不能超过 $O(\sqrt n)$ 的 bound 即可.

讨论区里有两个不同的 $O(n \log n)$ 的做法, 留坑待填.

Round 3

[C] Sumy

注意到答案肯定是一段后缀合法, 所以二分一下即可.

[B] Mopadulo

记 $S_i = \left(\sum_{k=1}^i A_i\right) \bmod P$, 那么有以下显然的转移: $$ f_i = \sum_{j < i} [(S_i-S_j) \equiv 2 \pmod P] f_j $$ 根据 $S_j$ 与 $S_i$ 的大小关系即可知道会不会多加一个 $P$, 开两个树状数组维护一下就好了. 时间复杂度为 $O(n \log n)$

[A] Wystawa

首先, 我们先令每个 $i$ 取 $\min (a_i,b_i)$, 这样肯定会得到一组最优的方案, 但这个方案不满足恰好选了 $k$ 个 $a$ 的限制.

因此, 问题转化成了, 有 $n$ 个整数 $a_i,b_i$, 且 $\mathbf{a_i \leq b_i}$, 需要恰好选 $k'$ 个 $a_i$ 换成 $b_i$, 最小化最大子段和.

考虑以下求最大子段和的算法:

  • 初始时 $ans \leftarrow 0, sum \leftarrow 0$
  • 对 $i=1, 2, \cdots, n$:
    • $sum\leftarrow \max(0, sum + a_i)$
    • $ans \leftarrow \max(ans, sum)$

我们考虑对着这个过程 dp. 我们需要知道的信息有 $(i,j,sum,ans)$ - 其中 $i$ 表示现在考虑到哪一个数, $j$ 表示已经替换了多少个数. 注意到我们可以通过二分答案去掉 $ans$ 这一维度 - 只要保证他不超过我们当前二分的值 $mid$ 即可.

因此, 我们不妨设 $f_{i,j}$ 表示若当前考虑到第 $i$ 个数, 已经换了 $j$ 个 $b_*$, 且此时最大子段和不超过 $mid$ 的情况下, $sum$ 的值最小能是多少. 转移时秩序枚举这个数换还是不换, 并判定是否仍满足条件即可. 时间复杂度与空间复杂度均为 $O(n^2)$.

注意到整个问题是个费用流, 所以显然 $f_{i,*}$ 是凸的, 我们直接使用 std::set / std::priority_queue 来维护差分数组, 每次转移时会改头部的元素并删掉所有的负数. 容易发现只要我们把相同的一段 $0$ 缩起来那么复杂度就是对的. 在维护的过程中记录一下是怎么转移过来的即可构造出方案.

代码写了一年.jpeg

Round 4

[C] Ranking sklepów internetowych

首先注意到, 如果我们单独选出 $n$ 这个元素, 那么我们会得到的答案为 $2n+1$. 容易发现我们肯定不能比这个更优, 这是因为长为 $2l+1$ 的区间中位数最大也只能是 $n-l$.

对于计数, 我们直接枚举区间长度, 维护一下区间端点的合法区间即可.

[B] Skrzyżowania

考虑一个固定的起点 $s$, 假设我们在某个时刻 $T_0$ 中暴力 BFS 出所有可达的点, 记 $A_{x,y}$ 表示 $(x,y)$ 是否可达, 那么我们注意到如果 $(x,y)$ 可达, 那么我们考虑 $A_{x,y},A_{x+1,y},A_{x,y+1},A_{x+1,y+1}$, 一定长成以下三种矩阵之一: $$ \left[\begin{matrix} 1 & 1\\ 0 & 0\\ \end{matrix}\right],\left[\begin{matrix} 1 & 0\\ 1 & 0\\ \end{matrix}\right],\left[\begin{matrix} 1 & 1\\ 1 & 1\\ \end{matrix}\right] $$ 这是因为任意时刻任意路口水平线路与竖直线路至少有一条能走. 这便意味着, 我们合法的可行区间一定是一个矩形, 且这个矩形要么水平方向无限延伸, 要么竖直方向无限延伸.

考虑一次询问 $(x_1,y_1) \to (x_2,y_2)$, 我们将会说明, 其答案要么是从第 $x_1$ 行任意一点走到 $x_2$ 行任意一点的时间, 要么是从第 $y_1$ 列任意一点走到 $y_2$ 列任意一点的时间.

为什么呢? 以第一个 Case 为例, 假设初始时起点可达的点是延水平方向无限延申的, 那么我们考虑任意一个 $R_{x_1} \to R_{x_2}$ 的方案, 我们在第一步肯定可以直接走到起点(因为水平方向的点均可达). 随后, 如果我们走到终点的时候仍然是水平延申, 那么我们可以直接走到正确的终点. 否则, 此时可达区域必定是竖直延申. 那么注意到整个平面一定是被若干个这样竖直方向无限延伸的矩形划分了, 在这之前, 我们一定可以选择进入哪一个竖直划分的区域, 且无论走到哪里都是立刻走到终点, 所以这一定是一种合法的方案.

这告诉我们两个维度是独立的, 我们只需要解决一维的问题. 不妨假设我们考虑如何解决水平方向的问题. 注意到整个地图的周期是 $k=\operatorname{lcm}(1,2,3,\cdots, t) (t=8)$, 那么首先我们对于每个 $i$, 我们可以 $O(n \cdot \frac{k}{w})$ 算出这两行之间什么时候可达, 建图的时间复杂度为 $O(nmk/w)$. 随后, 我们用点 $f_{i,j}$ 表示目前在第 $i$ 行, 时间模 $k$ 为 $j$ 的一个状态. 由于我们肯定会贪心地往右走, 所以如果一个点有往右的边, 那么就一定不会走往下的边. 把这样的边去掉后, 图显然是无环的, 所以我们直接对森林中的每一棵树 dfs 即可维护出需要的信息. 询问时只需要找到对应点的深度大力差分以下即可.

第一步的过程比较慢, 可以优化: 我们直接爆搜出所有可能的红绿灯 bitset 的状态, 预处理它们 and 的结果即可. 复杂度是 $O(4^t \cdot k/w + nm)$ 的.

[A] Areny

Unsolved.

Round 5

[C] Butelki

状态总数是线性的, 所以直接 BFS 即可.

[C] Drzewo czerwono-czarne

首先特判掉以下平凡 Case:

  • $c\equiv c'$, 输出 Yes
  • $c$ 中只有一种颜色, 输出 No
  • $c'$ 中, 任意 $(u,v) \in E$ 都有 $c'_u \ne c'_v$, 输出 No

前两个 Case 显然, 第三个 Case 是因为我们最后一次操作的时候肯定会造出来两个相同颜色的点, 所以不可能没有这样的点.

否则, 我们分类讨论:

  1. 若存在某个度数 $\geq 3$ 的点, 输出 Yes
    1. 不妨假设这个点是 $x$, 且 $(x,a) \in E, (x,b) \in E, (x,c) \in E$
    2. WLOG 设 $c_x = 0$, 我们先证明一定可以转化成 $c_a=0,c_b=c_c=1$ 的 Case:
      1. 如果初始就满足, 显然合法.
      2. 若 $c_a=c_b=c_c=1$, 那么我们直接一次操作改 $c_a$ 为 $0$ 即可.
      3. 若 $c_a=c_b=0,c_c=1$, 那么我们一次操作改 $c_x$ 为 $1$ 即可.
      4. 否则, 任取一个有 $1$ 的点然过去即可.
    3. 从上可知, 只要我们想, 我们就可以造出这种特殊的结构. 现在我们的目标是让最后答案中这四个点的结构也长成这个样子.
    4. 如果在最后答案中, $c'_x = c'_a $ (或 $c'_b, c'_c$), 那么我们只要调一下颜色就正确了.
    5. 因此, 需要解决的 Case 为 $c'_x \ne c'_* (* \in \{a,b,c\})$. 根据平凡 Case 3, 我们肯定能找到 $(u,v)$ 使得 $c'_u = c'_v$. 不妨设 $u$ 是离根较近的一个点, 那么我们将 $u$ 到根路径上的点按顺序写下来: $\lambda_1, \lambda_2, \cdots, \lambda_t$
      • WLOG, $\lambda_1 = u, \lambda_{t-1} = a,\lambda_t = x$
      • 我们令 $c''_{\lambda_1} = c'_{\lambda_2}, c''_{\lambda_2} = c'_{\lambda_3}, \cdots, c''_{\lambda_{t-1}} = c'_{\lambda_t}$. 其余点仍满足 $c''_i = c_i$
      • 注意到如果 $c''$ 有解, 那么 $c'$ 立刻有解, 只要从底向上把这条链复原回去即可.
    6. 所以我们把 5 的情况都转化成了 4. 对于 4 的情况, 我们直接从底向上依次修每个叶子即可, 同样讨论一下颜色是怎么传的, 发现我们总是可以在不破坏这四个特殊点的结构的前提下把答案传过去.
  2. 否则, 转化成了序列上的问题.
    1. 如果序列开头的元素不一样, 那么我们只能把头给删掉, 因为我们只能merge两个连续段, 不能swap或split
    2. 如果删掉以后, $c$ 的连续段数目 $<$ $c'$ 的连续段数目就是 No, 否则就是 Yes
    3. 证明仍然是类似的调整. 注意到我们总是有一段的长度 $\geq 2$, 所以我们一定可以通过伸缩一段让前面一段自由.

总的时间复杂度为 $O(n)$

[B] Autostrada

Unsolved

[B] Desant 2

我们建一张图:

  • $i \to i+1$, 边权为 $0$
  • $i\to i+k$, 边权为 $\sum_{j=i}^{i+k-1} a_j$

那么一组询问的答案就是 $u \to v$ 的最长路. 注意到如果我们把每个数表示成 $x=ik+j (0 \leq j < k)$ 的形式, 那么这张图基本是一个网格图. 仿照 ZJOI 旅行者那一道题目分治即可. 注意到比较恶心的是 $(i,k-1) \to (i+1,0)$ 的边, 所以我们在分治的时候需要看一下, 如果这是第一次沿着 $i$ 这一维切的话, 需要把第一行的贡献也跑出来.

直接写的话可能会得到一个跑40秒的垃圾做法, 所以不要建图BFS, 直接手动算一下每一类边的贡献, 这样可以快 10 倍.

时间复杂度 $O(n^{1.5} \log n)$

[A] Zbiory niezależne

~~ GF 题狗都不做。~~

这个题之前我搬了个一模一样的, 视频题解里讲了, 暂时先不写了, 以后补一个(

[A] Fiolki

我们回顾一下这一道题: https://qoj.ac/problem/61

发现这道题与这个题基本一样, 我们同样对前 $k$ 个点取一个单位向量, 后面每个点都是其入边对应点的随机线性组合. 那么区间 $[l, r]$ 的答案就是 $\vec v_l, \vec v_{l+1}, \cdots, \vec v_{r}$ 张成线性空间的秩.

我们枚举 $r$, 并尝试将向量插入线性基中. 插入时, 我们在消元之前看一下这个元的编号是不是比它小, 如果小的话就swap以下, 这样保留出来的就是最大的一个线性基. 求出线性基以后维护一下对应的区间即可.

时间复杂度为 $O(md+nd^2)$. 有点卡常数, 需要精细实现一下.

Petrozavodsk Winter 2022 开始报名了

2021-12-23 22:34:05 By Qingyu

Moscow International Workshops 2021 Day 2 题解 (aka GP of Southern Europe)

2021-11-30 10:23:33 By Qingyu

A. ABC Legacy

记 $c_A, c_B, c_C$ 分别表示每个字母的出现次数, $f_{AB}, f_{AC}, f_{BC}$ 表示每种匹配的出现次数, 那么显然有 $$ \begin{cases} c_A = f_{AB}+f_{AC}\\ c_B = f_{AB}+f_{BC}\\ c_C = f_{AC}+f_{BC}\\ c_A+c_B+c_C = 2n \end{cases} $$ 于是显然可以解出 $f_{AB}=n-c_C, f_{AC}=n-c_B, f_{BC}=n-c{A}$, 即每种匹配的数量是固定的. 考虑所有含有 B 的匹配, 注意到最后还要匹配 AC 型的pattern, 所以我们在选择匹配 B* 的时候, 肯定会尽量选择后缀一段 A 和前缀一段 C, 那么匹配的时候找到第一个能匹配的 B 显然是最优的. 如果最后配不出来, 就是无解.

B. New Queries On Segment Deluxe

留坑

C. Counting Phenomenal Arrays

首先说一下我们在现场的做法: 不妨设 $a_1\leq a_2 \leq \cdots \leq a_n$, 只计数有序的序列数量, 乘上对应的系数即可.

注意到 $a_1a_2\cdots a_n = a_1+a_2+\cdots+a_n \leq na_n $, 所以我们有 $a_1a_2\cdots a_{n-1} \leq n$, 即我们选出的数中, 去掉最大的数, 乘积不能超过 $n$.

而另一方面, 当我们确定了前 $n-1$ 个数后, 我们可以通过解方程 $Px = S + x$ 来求出 $x$ 的值, 因此我们不难设计出一个 dp: 设 $f_{i,j,\pi,\sigma}$ 表示已经填了 $i$ 个数, 上一次填的是 $j$, 目前乘积是 $\pi$, 总和是 $\sigma$ 的贡献总和.

但上述 dp 的复杂度过高, 我们完全无法接受. 但是注意到大多数状态是完全不可达的, 因此我们不妨将上述过程写成一个搜索的形式, 只搜索可能达到的状态. 通过暴力实现搜索, 我们可以轻松通过 $n \leq 1000$ 的数据, 但仍然无法通过本题.

注意到我们可以添加许多剪枝. 其中最重要的一个是, 我们考察当前填出来的状态, 并通过解方程解出此时最后一个数能填啥. 如果这个解出来的值已经小于目前的 $j$, 那么再填下去就没有意义了, 我们直接认为不合法. 同时, 再添加若干个不同的优化(例如不需要去枚举1的数量,最后算答案再计算), 我们便可以轻松通过本题.

上述算法看起来不太科学, 通过地比较侥幸, 那么有没有更靠谱的算法? 当然是有的. 我们还是计算有序序列的数量, 但这次我们规定 $a_1>1$. 我们不妨设 $\varphi(a) = \sum(a) - \prod(a)$, 则我们最终要求 $\varphi(a)=0$. 但注意到, 若 $b_i > 2$, 则必有 $\varphi(a_1 \cdots a_k) \leq \varphi(a_1 \cdots a_{k+1})$, 而初始时我们有 $\varphi(a_1)=0$, 因此我们只要开始填数, $\varphi$ 值就恒小于等于 $0$, 只能在最后填 $1$ 来补救.

由于一个 $1$ 只能恰好将 $\varphi$ 值加 $1$, 所以显然 $\varphi$ 值不能超过 $n$. 我们仿照上述过程实现一个 dfs, 当我们搜出一个 $b_1,b_2,\cdots,b_k(b_1>2, b_i \leq b_{i+1})$, 其积为 $\pi$, 和为 $\sigma$ 时, 我们有 $\varphi(b) = \pi - \sigma$, 显然我们只有在最后填恰好 $-\varphi(b)$ 个 $1$ 才能让他有可能有贡献, 所以我们任取一个不含 1 的序列, 其只有不超过 1 种方法使得其有贡献. 最后我们添加 $k$ 个 $1$ 的方案数即为 $\binom{k-\varphi(b)}{-\varphi(b)}$, 乘上对应贡献的系数即可.

所有元素大于 1, 且乘积不超过 $n$ 的序列非常的少, 通过暴力打表我们可以验证总的可能状态数可以接受, 且我们每次递归都能找到一个对应的解, 故整个过程的复杂度是有保证的.

D. LIS Counting

留坑

E. Flood Fill

首先注意到, 如果两个块 $A,B$ 是相邻的, 那么我们不可能同时将 $A,B$ 均反色. 因此, 我们的操作相当于选一个互不相邻的联通块集合 $S$, 使得最小化 $\sum_{i\in S}f(i) + \sum_{i \notin S}g(i) = \sum g(n) + \sum_{i \in S} (f(i)-g(i))$, 这是一个二分图最大权独立集问题, 所以直接写个网络流就好了.

F. to Pay Respects

首先注意到, 我们的操作可以分为两类, 一类减小 $r$, 另一类不减小.

对于不减小的那一类, 我们考虑最后一次这样的操作在时刻 $T$, 如果存在 $T_0 < T$ 且 $T_0$ 你没有操作, 那么你把这次操作转移到 $T_0$ 显然更优, 这是因为反正你也不能减小了, 不如先操作让对面增长地慢一些.这说明我们第二类操作一定占据了所有操作的一个前缀. 存在一个显然的贪心, 即考虑每个时刻 $i$ 对答案的贡献 $\Delta_i$, 如果这个时刻你操作, 那么如果对面操作, 你的贡献就是 $(n-i+1) \cdot (p+r)$, 否则是 $(n-i+1) \cdot p$, 这是因为你显然不会让对面有值的时候放过它到后面再操作, 所以只有对面是 $1$ 的时候才有可能减小. 这样我们直接排序并取前 $K$ 大, 时间复杂度为 $O(n \log n+K)$.

事实上, 根据进一步分析, 我们显然会从间断点后取一个 $1$ 的前缀操作, 所以我们可以直接做一个类似双指针一样的操作, 一开始取前 $k$ 个, 每次取后面第一个调整即可. 时间复杂度为 $O(n+K)$.

G. Replace Sort

首先将 $B$ 排序, 随后发现我们替换的时候位置显然是单调的. 设 $f_{i}$ 表示将 $A$ 的前 $i$ 个数排序, 且最后一个数不变的最小代价, $g_{i,j}$ 表示将 $A$ 的前 $i$ 个数排序, 且最后一个数替换成了 $B_j$ 的最小代价, $p(x)$ 表示最大的一个 $k$ 使得 $B_k \leq x$.

转移时, 对于 $f$ 直接枚举前面放没放:

  • $f_{i} \leftarrow f_{i-1} (A_{i-1} \leq A_i)$
  • $f_i \leftarrow \min_{1 \leq j \leq p(A_i)} g_{i,j}$

对于 $g$, 我们注意到如果前面替换成了 $B_k$, 那么这次一定替换成 $B_{k+1}$, 因为填更大的只会让后面的限制变得更严格, 所以:

  • $g_{i,j} \leftarrow f_{i-1} + 1 (A_{i-1} \leq B_j)$
  • $g_{i,j} \leftarrow g_{i-1,j-1} + 1$

直接做复杂度显然是 $O(n^2)$ 的, 注意到我们可以使用线段树来优化 $g$ 对 $g$ 的转移与 $g$ 对 $f$ 的转移 (只需要区间取min, 区间求min即可. 平移操作没什么用, 加的1全都是全局加). 总的时间复杂度为 $O(n \log n)$.

H. Werewolves

注意到如果一个联通块有贡献, 那么造成贡献的颜色只有恰好一种, 所以我们可以枚举这种颜色, 然后数有多少个有贡献的联通块, 这可以通过一个简单的树上背包 ( $dp_{i,\delta}$ 表示考虑以 $i$ 为根的子树, $i$ 必须选, 出现次数最多的元素减去总元素为 $\delta$ 的方案数 ), 总的时间复杂度为 $O(n^3)$.

注意到 $\sum_{i=1}^n c_i = n$, 而我们枚举颜色 $i$ 做树上背包的时候, size 显然是不超过 $c_i$ 的, 所以我们只需要做大小不超过 $k$ 的树上背包, 它的时间复杂度是 $O(nk)$ 的, 具体之前我讲杂题的时候讲了就跳过了.jpeg

综上, 总的时间复杂度为 $O(n^2)$

I. Colourful Permutation Sorting

留坑

J. Jason ABC

注意到两次操作是一定够的, 我们设 $f_{c,i}$ 表示 $\sum_{i=1}^n [s_i=c]$, 求最小的 $j$ 使得 $\max_{i \in \Sigma} f_{i,j} \geq n$, 随后两次操作把剩下两种不够的字符补齐即可.

所以只需要特判零次和一次操作. 零次操作显然, 一次操作的话, 我们枚举这种操作的是什么字符, 然后在枚举左端点, 右端点显然是单调的, 于是就稍微维护一下就做完了. 时间复杂度 $O(n)$

K. Amazing Tree

首先注意到第一个元素一定是某一个叶子, 不妨设编号最小的叶子为 $x$, 则我们序列的第一个元素必定为 $x$.

不妨设我们 dfs 时的根为 $r$, $x$ 的唯一邻居为 $y$

  1. 若 $r = y$, 则我们在访问完 $x$ 后, 相当于从 $y$ 开始依次遍历每一个子树(除了 $x$), 显然我们还是会走到最小的叶子所在的子树内, 就变成了一个根确定的子问题.
  2. 若 $r \ne y$, 则相当于要选择一个 $y$ 的子树, 当作根所在的联通块, 显然我们取最小叶子最大的那个子树当根是最优的, 随后 dfs 的时候, 非最大子树的相当于根已确定, 直接走完所有的子树, 剩下的那一个还是需要做类似的过程确定最优的 $r$

L. Primes and XOR? Nonsense

留坑

M. Many LCS

留坑

N. Max Pair Matching

不妨设 $a_i \leq b_i$, 那么 $w(i,j) = \max(b_i-a_j,a_i-b_j)$. 那么最大匹配的权值就是选出恰好 $n$ 个点当作 $b_i$, 另外 $n$ 个点当作 $a_i$, 最大化他们相减的值. 我们可以假设 $2n$ 个点全都选 $b_i$, 那么把一个 $b_i$ 改为 $a_i$ 的代价即为 $a_i+b_i$, 按照代价排序选 $n$ 个最小的减去就是答案.

共 48 篇博客
  • 1
  • 2
  • 3
  • 4
  • 5