省选模拟赛
2024.12.18 炼石 #4
\(100+42+0=142\)。
Problem A. 凹包
题意:
小凯发明了一个关于凸多边形的游戏。
小凯在游戏开始前生成了一个 \(n\) 个点的凸多边形。
同时,他还在凸多边形内生成了一个关键点 \(C\) 和若干个得分点。保证所有关键点和得分点均严格在凸多边形内部,且凸多边形上的点不存在三点共线。
Alice 和 Bob 玩了这个游戏,Alice 先手。每次操作选择一个当前多边形上的顶点,并将其移动到 \(C\)(如果 \(C\) 处已经有了一个顶点,则这些顶点会被合并)。一次操作合法当且仅当存在一个得分点,在操作前在多边形内,而在操作后在多边形外。保证对于所有可能出现的状态,任何得分点都不在多边形的边界上。
需要注意的是,在游戏过程中,多边形可能不是凸多边形,也可能退化(即,变成一条线段)。如果一个人无法进行一次合法的操作,那么他就输了。
这个游戏太简单了,所以小凯对游戏做了一些修改,每次修改形如:
+ x y:表示增加一个得分点 \((x,y)\),保证 \((x,y)\) 在操作前不是得分点。- x y:表示删除一个得分点 \((x,y)\),保证 \((x,y)\) 在操作前是得分点。
你需要对初始状态和每次修改后的状态回答:当前状态是 Alice 必胜还是 Bob 必胜。
记 \(n\) 为凸多边形点数,\(m\) 为得分点数量,\(q\) 为修改次数。
对于所有数据,有:
- \(1 \leq n \leq 10^4\)。
- \(1 \leq m \leq 10^5\)。
- \(1 \leq q \leq 10^6\)。
- 所有点的横纵坐标在 \(\left[-10^9, 10^9\right]\) 之间,且均为整数。
- 凸包上的点没有三点共线,关键点和所有得分点严格在凸包内部,所有得分点互不相同。
- 保证对于所有可能出现的状态,任何得分点都不在多边形的边界上。
- 保证每次修改操作后依然符合上述条件。
时限 \(3\) 秒,空间限制 \(1\) GB。
解法:
先考虑无修改。容易发现每次选择一个顶点移动到 \(C\) 会使得相邻两个区域内的得分点移出多边形。显然每个得分点根据关键点和凸包的关系会唯一对应到凸包某条边上。记 \(a_1,a_2,\cdots,a_n\) 表示对应到每条边的得分点数量,题意转化为每次选择序列上相邻两个值,满足两个都不是 \(0\),然后将两个数都变为 \(0\)。无法操作的人输。特别地,序列第一个数和最后一个数也相邻。
显然每个 \(a_i\) 具体为多少是不重要的,只需要考虑 \(a_i = 0\) 或 \(a_i=1\)。
特判所有 \(a_i=1\)。
现在考虑存在 \(a_i=0\),容易发现整个序列可以通过 \(0\) 分为若干段,每段都形如 \(01\cdots 10\),每段独立,考虑 SG 函数。发现 \(01\cdots 10\) 本身的 SG 函数容易求出,\(O(n^2)\) 预处理即可。
关于确定每个点在哪条边上,这个只需要用到基础计算几何内容,将凸包上的点按照与 \(C\) 水平夹角排序后二分即可。
对于修改操作,使用线段树维护所有连续 \(1\) 段的 SG 异或值即可,或者使用 set 维护连续段也可。复杂度 \(O(n^2+(m+q)\log n)\)。
Problem B. 集合
题意:
定义一个非空的正整数集合 \(S\) 是好的,当且仅当 \(\forall x, y \in S\),有 \(\gcd(x, y) \in S\),即集合内任意两数的最大公约数都在 \(S\) 里。
定义比较两个不同的集合 \(A, B\) 大小的方法:
- 令 \(\max A, \max B\) 分别为 \(A, B\) 里的最大值。若 \(\max A \neq \max B\),则 \(A, B\) 的大小关系就是 \(\max A\) 和 \(\max B\) 的大小关系。否则 \(A, B\) 的大小关系是 \(A \setminus \{ \max A \}\) 和 \(B \setminus \{ \max B \}\) 的大小关系。定义 \(\max \emptyset = -\infty\)。
求第 \(K\) 小的好集合。
\(1 \leq K \leq 10^9\),时限 \(1\) 秒,空限 \(1\) GB。
解法:
根据观察大样例可以得到集合最大元素不会太大。事实上,对于 \(K=10^9\),集合最大元素不超过 \(37\)。下文令 \(B=37\)。
显然集合比较可以看作二进制比较。对于一个好的集合 \(S\),我们可以在 \(O(B^2)\) 的复杂度内求出下一个好集合 \(T\),具体来说,先将 \(S\) 加 \(1\),然后从高到低枚举 \(i\) 与 \(j<i\),尝试将 \(\gcd(i,j)\) 加入集合。于是我们得到了一个 \(O(B^2K)\) 的做法。
分块打表,可以通过。
Problem C. 城市建设
2024.12.21 炼石 #5
\(35+100+0=135\)。
Problem A. DS
Problem B. Floyd
题意:
一般来讲 \(O(n^3)\) 求无向图任意两点连通性的算法都用 Floyd 实现,示例代码如下:
void OldFloyd(int n){
for(int k=1; k<=n; k++){
for(int i=1; i<=n; i++) if(G[i][k]){
for(int j=1; j<=n; j++) if(G[k][j]){
G[i][j] = 1;
}
}
}
}
如果 \(n\) 比较大且执行 Floyd 的次数较多,那么容易超时(小 C 不知道可以用 bitset 优化做到 \(O(\frac{n^3}{w})\))
所以小 C 想出来个奇技淫巧,他限制了 Floyd 的轮数,只让它做 \(m\) 轮,这样复杂度就是 \(O(n^2 \cdot m)\) 的,示例代码如下:
void NewFloyd(int n, int m){
for(int k=1; k<=m; k++){
for(int i=1; i<=n; i++) if(G[i][k]){
for(int j=1; j<=n; j++) if(G[k][j]){
G[i][j] = 1;
}
}
}
}
这样的做法可以在某种程度上优化求连通性的效率,但是可能会出错,小 C 现在想知道,假如现在等概率随机生成一张 \(n\) 个点的简单无向图(即对于每对 \((i, j)\) \((i < j)\),\(g[i][j]\) 和 \(g[j][i]\) 有 \(\dfrac{1}{2}\) 的概率同时为 1,否则同时为 0。注意:这里我们默认认为对于任意的 \(i\) 都满足 \(g[i][i] = 1\)),并经上述代码一轮 \(m\) 轮 Floyd 后,得到的结果完全正确的概率是多少(即执行两份代码的得到的 \(G\) 数组完全相同),你只需要输出这个概率对大质数 \(p\) 取模后的结果即可。
\(1 \leq n, m \leq 150\),\(10^8 < p < 1.01 \times 10^9\),\(p\) 是质数,\(2\) 秒。
解法:
好题。
求概率等价于求方案数。
容易发现进行 \(m\) 轮 Floyd 本质求出的 \(G_{i,j}\) 其实是 \(i\) 到 \(j\) 是否存在一条路径,路径上除了端点的点编号最大值不超过 \(m\)。
首先求出 \(h_i\) 表示 \(i\) 个点的无向简单连通图方案数。这个是简单的。
其次,考虑求 \(g_{i,j}\) 表示 \(n=i,m=j\) 的无向简单连通图方案数,转移考虑将 \(\leq j\) 的点与 \(>j\) 的点分开。然后考虑 \(>j\) 的所有点都要往 \(\leq j\) 的点构成的连通图中连至少一条边。这部分是容易转移的。
接着考虑求 \(f_{i,j}\) 表示 \(n=i,m=j\) 的答案。和 \(g\) 的区别在于不要求连通。转移考虑常见方法,枚举点 \(i\) 所在连通块大小。但是我们还需要枚举这个连通块中有多少点编号 \(<j\),总复杂度 \(O(n^4)\),适当卡常即可通过。
代码中 \(f\) 和 \(g\) 是反的。
Problem C. Paper
2024.12.25 炼石 #6
\(100+5+0=105\)。
Problem A. 游戏
简单博弈论。
Problem B. 字典序
题意:
一个 \(k\) 阶字符串是一个长度为 \(\sum \limits_{i=1}^k i\) 的,字符集为 \(\texttt{a}\) 到 \(\texttt{z}\) 的字符串,且恰好出现了 \(k\) 种字符,每种字符出现次数不同,且相邻两个字符不同。
给定 \(k,n\),求字典序第 \(n\) 小的 \(k\) 阶字符串。
\(1 \leq k \leq 26\),\(1 \leq n \leq 10^{18}\)。
解法:
看着没啥道理能做,但事实上写个爆搜记一下每种前缀集合对应的方案数即可。因为 \(k\) 阶字符串个数其实非常大,爆搜跑的很快。
Problem C. 集合选取
原题:CF1446H。
题意:
有 \(n\) 个顾客与 \(n\) 个物品,每个顾客有一个排列 \(b_i\) 表示他对物品喜好程度的排名。
你有一个物品分配方案的排列 \(a\),表示 \(i\) 号顾客拿到第 \(a_i\) 个物品。
称一个分配方案 \(a\) 是好的,当且仅当不存在一个非空集合 \(S\),使得存在一个分配方案 \(a'\) 满足:
- \(\forall i \in S, a'_i \in S\)
- \(\forall i \in S\),第 \(i\) 个顾客相对 \(a_i\) 更喜欢 \(a'_i\)(不要求严格更喜欢 \(a'_i\),即 \(a_i\) 可以等于 \(a'_i\))
- \(\exists i \in S\),第 \(i\) 个顾相对 \(a_i\) 严格更喜欢 \(a'_i\)。
输入物品分配方案的排列 \(a_1,a_2,\cdots,a_n\),请求出有多少种不同的 \(\{b_1,b_2,\cdots,b_n\}\) 排列组使得分配方案 \(a\) 是好的。可以证明对于任意一个 \(b\),都存在唯一的好排列 \(a\)。
\(n\le 40\),答案对 \(10^9+7\) 取模。
解法:
首先考虑为什么对于任意一个 \(b\),都仅存在唯一的 \(a\)。
考虑构建有向图,对于每个 \(i\),连边 \(i \rightarrow b_{i,1}\),意思是每个点向其最喜欢的物品连边。显然图是一个内向基环树森林。不难证明每个环都是要取的,也就是环上的人获得的物品都是其最喜欢的物品。然后将环上点删去,对剩下点继续建图,每个人向第二喜欢的物品编号连边,以此类推。显然对应的好序列唯一确定。
考虑排列 \(a\) 构成的图,连边 \(i \rightarrow a_i\),每个环都是我们生成过程中基环树上的一个环。继续考虑每个人的 \(b\) 怎么确定。我们在 \(a\) 的排列构成的图基础上,对于每个点 \(i\),将其喜爱度比 \(a_i\) 更高的连边,也就是向对应的 \(b\) 序列中 \(a_i\) 前面的点连边。不难发现新的图不能存在包含新的边的环。
将所有环缩点,新的图是一个 DAG。
考虑新图对应的 \(b\) 数量,记 \(deg_i\) 表示 \(i\) 的出度,则对应 \(b\) 数量为 \(\prod \limits_{i} deg_i!(n-deg_i-1)!\)。分别是 \(i\) 的喜爱排列中 \(a_i\) 前后的排列方案数。
这样问题不弱于 DAG 计数,根据 DAG 可以通过每次删去入度为 \(0\) 的点最终变为空图,可以设计一个状压 DP,记 \(f_S\) 表示 \(S\) 子集生成的 DAG 排列对应的 \(b\) 数量之和,转移考虑枚举入度为 \(0\) 的点的一个子集然后子集反演,这样复杂度为 \(O(3^c)\),\(c\) 为 \(a\) 的环数量,无法通过。
进一步,考虑图中存在很多长度相同的环,记状态 \((c_1,c_2,\cdots,c_n)\) 表示每种长度的环的个数,这样状态数不超过 \(1440\),转移直接枚举 \(c'_i \leq c_i\) 的子集,算贡献时要加一个组合数。
2024.12.29 炼石 #7
\(40+100+15=155\)。
Problem A. 在海的指尖 II
题意:
给定 \(n,m\) 和一个长度为 \(m\) 的单调递增序列 \(a_1,a_2,\cdots,a_m\),求有多少 \(1\) 到 \(n\) 的排列满足 \(a_1,a_2,\cdots,a_m\) 是其某个最长上升子序列。可以发现答案不会超过 long long 范围。
\(1 \leq m \leq n \leq 21\),\(1 \leq a_i \leq n\) 且 \(a\) 单调递增,\(3\) 秒,\(1\) GB。
解法:
或许你在 DP 套 DP 例题中遇到过这个题,但是原题范围是 \(n \leq 15\),原题做法大概是考虑最长上升子序列的 \(O(n \log n)\) 基于维护单调队列的做法,记 \(f_S\) 表示目前状态为 \(S\) 的方案数,其中 \(S\) 是一个三进制数,每一位为 \(0\) 表示这个数还未加入序列,为 \(1\) 表示其在单调队列中,为 \(2\) 表示其已经考虑过但不在单调队列中。总复杂度 \(O(3^nn)\),能通过原题但不能通过此题。
考虑另一个方式 DP,我们根据值域从小到大插入,并维护 \(f_i\) 表示目前序列的 \([1,i]\) 这段前缀的最长上升子序列长度。不难发现 \(f_i - f_{i-1} \in \{0,1\}\),于是可以用一个二进制数记录所有 \(f_i\)。于是进行 DP,记 \(g_{i,j,S}\) 表示值域上已经插入了 \([1,i]\),目前的最长上升子序列 DP 结果为 \(S\),目前最大的在给定序列中出现的数是序列中第 \(j\) 个。转移是简单的。注意到 \(S \leq 2^i\),总复杂度为 \(O(n^2 2^n)\),可以通过。
Problem B. 于星的彼岸
题意:
给定 \(n,d\) 和一个长度为 \(n\) 的序列。称一个长度为 \(k\) 的序列是好的当且仅当其小到大排序后相邻两个数差不超过 \(d\)。
现在给定 \(q\) 次询问,每次给定区间 \([l,r]\),求 \(a\) 序列的 \([l,r]\) 区间有多少个子区间是好的。允许离线。
\(1 \leq n, q \leq 3 \times 10^5\),\(1 \leq a_i, d \leq 10^9\),\(2\) 秒,\(1\) GB。
解法:
比较套路的题。
排序一般都不好处理,考虑转化判定方式。对于区间 \([l,r]\),可以发现判定其为好等价于对于所有区间中非最大数 \(x\),区间中都存在 \((x,x+d]\) 内的某个数。
对于每个 \(i\) 找到其左侧和右侧第一个在 \((a_i,a_i+d]\) 范围内的数,记其位置分别为 \(L_i,R_i\),则判定区间 \([l,r]\) 变为判断是否对于所有 \(i \in [l,r]\),都有 \([l,r]\nsubseteq(L_i,R_i)\),即 \(r \geq R_i\) 或 \(l \leq L_i\)。
现在我们考虑 \(q=1,l=1,r=n\) 怎么做,即求整个序列有多少区间符合条件。
对右端点扫描线,记现在右端点为 \(r\),线段树每个点 \(l\) 维护 \([l,r]\)。对于每个 \(i\),\(r < R_i\) 时有限制,若区间包含 \(i\),则 \(l \leq L_i\)。扫描线时容易动态维护这些限制,区间加区间 \(\min\) 数量即可维护。但是区间最大值的限制并没有被移除,考虑可能成为区间最大值的只有 \([1,r]\) 的后缀最大值,维护单调栈并对单调栈中的元素特殊处理即可。
对于原题,不难发现只需要维护区间历史和即可。
复杂度 \(O((n+q)\log n)\)。
Problem C. Capella
题意:
给定 \(n,m\),有一张 \(n\) 个点的无向完全图,每条边上写有 \([1,m]\) 的整数颜色,初始时给定每条边颜色。你要判断是否能增加 \(m-n+1\) 个点使得图变为 \(m+1\) 个点的完全图,且每个点的邻边恰好出现了 \([1,m]\) 的所有颜色。若有解,需要输出构造。
多测,\(T \leq 5\),\(1 \leq n -1 \leq m \leq 200\),时限 \(1\) 秒。
解法:
考察一些必要条件。
首先,有解必要条件之一是 \(2 \mid m+1\),因为每种颜色构成了一个大小为 \(\dfrac{m+1}{2}\) 的匹配。
同时,记 \(p_i\) 表示颜色 \(i\) 在给定的图中的匹配数量,则我们要求 \(m-n+1 \geq n-2p_i\),即 \(2n-2p_i \leq m+1\)。
可以证明,上述两个条件同时成立是有解的充分必要条件。具体地,我们给出一个构造性证明。
设目前图点数为 \(n\),我们增量构造,直到 \(n=m+1\)。
每次,我们建立一个网络流模型,左侧 \(m\) 个点表示每种颜色,右侧 \(n+1\) 个点,其中前 \(n\) 个点是目前图上的点,向汇点连容量为 \(1\) 的边。第 \(n+1\) 个点向汇点连容量为 \(m-n\) 的边。左侧第 \(i\) 个颜色向右侧第 \(j\) 个点连边当且仅当点 \(j\) 邻边中不存在 \(i\)。同时若 \(2n-2p_i \neq m+1\),则向右侧 \(n+1\) 点连权值为 \(1\) 的边表示这种颜色目前可以不使用。我们只需证明每次都存在大小为 \(n\) 的流,这样即得证。
注意到可以把网络流拆成二分图形式并考虑所有点的度数,进一步可以发现图是正则二分图(每个点度数相同),必然有完美匹配,于是证毕并且我们得到了构造方法。
2024.12.30 GZOI 冬令营训练 #1
Problem A. 下雨
题意:
给定 \(T\) 组询问,每次给定 \(n\),定义一个满足 \(\sum a_i \leq n, a_i > 0\) 的序列的权值为 \(\sum a_i!\),求所有序列的 \(\operatorname{MEX}\) 对 \(998244353\) 取模的结果,特别地 \(a\) 若长度为 \(0\) 则其权值为 \(0\)。
\(1 \leq T \leq 10^5\),\(1 \leq n \leq 10^{15}\)。
解法:
考虑判定一个数能否表示为阶乘之和。从大到小贪心即可。
对于原题,将 \(n\) 增加一,不难发现我们尽可能希望得到 \(1! \times 1 + 2! \times 2 + \cdots\),但是最终可能会导致多出来一些数,那么将 \((c - n)!\) 减去一个即可。
由于 \(\sum \limits_{i=1}^n i^2\) 是 \(O(n^3)\) 级别,复杂度 \(O(T \log n+\sqrt[3]{n})\)。
Problem B. 沙尘暴
题意:
小 L 生活在一座沙尘暴肆虐的城市,这个城市里有 \(n\) 个小 L关心的地点。小 L 记得在沙尘暴来袭之前,从第 \(i\) 个地点到第 \(j\) 个地点要消耗 \(w_{i, j}\) 的时间,保证 \(w_{i,j}=w_{j,i}\)。
由于常年累积的沙子,现在第 \(i\) 个地点距离地表的高度是 \(h_{i}\),因此从第 \(i\) 个地点到第 \(j\) 个地点消耗的时间变为了 \(C|h_{i} - h_{j}| + w_{i, j}\)。小 L 拥有控制沙子程度的能力,所以她可以在一开始花费 \(k d_i (k > 0)\) 的时间让 \(h_i\) 增加或减少 \(k\),但是因为地表及以下的部分并不是由沙子构成的,所以她并不能把任何地点的高度降到 \(0\) 以下。
现在小 L 想知道,对于任意一对地点 \(i, j\),她先消耗一些时间来修改 \(h\),再从消耗一些时间从地点 \(i\) 走到地点 \(j\) 花费的最小总时间是多少。注意这里对于每一对地点是独立计算的,即修改 \(h\) 是从初始的 \(h\) 来修改。
\(1 \leq n \leq 500\),\(0 \leq C, h_i, d_i \leq 10^7\),\(0 \leq w_{i,j} \leq 10^{14}\),\(3\) 秒。
解法:
假设我们现在需要求出 \(s\) 到 \(t\) 的答案。
考虑一条 \(s\) 到 \(t\) 的路径,我们将其上 \(h\) 没有被修改的点拉出来并分段,我们可以证明路径任意一段,假设这段左侧没修改的高度为 \(h_1\),右侧没修改高度为 \(h_2\),则整段必然是一个前缀都为 \(h_1\),然后后缀都是 \(h_2\)。感性理解还是很有道理的。
考虑求出 \(f_{i,j}\) 表示从 \(i\) 走到 \(j\),且路径每个点高度都变为 \(h_i\) 的最小答案,直接 Dijkstra 是 \(O(n^3 \log n)\) 的,注意到图是稠密的,使用非堆优化即可做到 \(O(n^3)\)。
然后求出 \(g_{i,j}\) 表示路径某段是 \(i\) 到 \(j\) 时这一段的最小答案。则 \(g_{i,j} = \min \limits_{k} f_{i,k}+f_{j,k}+C|h_i-h_j|-d_k|h_j-h_k|\),直接枚举即可做到 \(O(n^3)\)。
最后求答案再跑 \(n\) 次 Dijkstra 即可,总复杂度 \(O(n^3)\)。
Problem C. 宇宙射线
我也不会呢。
2024.12.31 GZOI 冬令营训练 #2
\(100+20+30=150\)。
Problem A. 万斯
题意:
给定 \(n,m,k\),考虑一个 \(n \times m\) 的棋盘,你需要在棋盘上放若干棋子满足以下条件或报告无解:
- 所有棋子构成一个联通块。联通是指两个棋子有公共边。
- 恰有 \(k\) 个 L 形。若一个 \(2 \times 2\) 的子正方形中有 \(3\) 个棋子,则构成一个 L 形。若有 \(4\) 个,则构成四个 L 形。
多测,\(T \leq 20\),\(3 \leq n, m, n\times m \leq 10^5\),\(0 \leq k \leq 10^9\),\(2\) 秒。
解法:
首先 \(k > 4(n-1)(m-1)\) 无解。
其次也不一定有解,但是直接构造的想法比较显然。
我们先构造出 \(4\lfloor \dfrac{k}{4} \rfloor\) 个 L 形,直接从上往下从左往右填 \(2 \times 2\) 矩形即可,但注意此时有可能最后一行没填满导致其实构造了 \(4\lfloor \dfrac{k}{4} \rfloor + 1\) 个 L 形,不过这没有太大的影响。
然后分类讨论剩下的 L 形需要为 \(0,1,2,3\) 的填法,注意 \(n,m\) 较小时有些填法会不符合限制,所以 \(n,m \leq 4\) 时可以爆搜。
这样分讨写起来会比较麻烦,赛时我写了很久。
其实有一种更为好写的做法,即构造完 \(4\lfloor \dfrac{k}{4} \rfloor\) 后,我们对目前黑色轮廓外的点随机加点或删点,显然比较快的次数内就能得到 \(k\) 个 L 形。
Problem B. 梨仙人掌
题意:
有 \(n\) 个人玩游戏,每个人在游戏开始前被划分到了两个阵营:好人和坏人。游戏是回合制的,每一回合有两个阶段:白天和夜晚。白天,所有还留着的人可以进行自由讨论,在讨论中每个人要确定自己投票的对象。投票结束后票数最多的人被淘汰。如果平票,则由系统在票数最多的人中随机选择一个人淘汰。晚上,所有留着的坏人可以商量并选择一个人淘汰。如果所有好人被淘汰,则坏人阵营获胜;反之所有坏人被淘汰,则好人阵营获胜。游戏过程中有一个随机数生成器,可以生成 \([0,1]\) 中的一个随机实数。任何玩家可以在任何时候使用这个随机数生成器。
假设所有人都是绝顶聪明的,即所有人会做出最利于自己阵营的决策。请回答应该将多少人分配到坏人阵营使得好人获胜的几率和坏人获胜的几率尽可能接近,并给出在这种情况下好人阵营更占优(输出 Good)还是坏人阵营更占优(输出 Bad)。如果游戏是完全平衡的则输出 Draw。
多测,\(T \leq 10^5\),\(2 \leq n \leq 10^5\),\(4\) 秒。
解法:
神秘结论题。
我们直接给出双方的游戏策略。
可以证明,坏人每天晚上直接选一个好人淘汰,白天所有人随机投票。
根据策略,可以直接进行 DP,记 \(f_{i,j}\) 表示共 \(i\) 个人且其中有 \(j\) 个坏人时,好人获胜概率。若 \(j>i-j\) 则 \(f_{i,j}=0\),因为每次坏人都可以把好人投出去。非边界情况时,白天每个人被投出概率相等,所以 \(f_{i,j} = \dfrac{i-j}{i} f_{i-2,j} + \dfrac{j}{i}f_{i-2,j-1}\)。直接做 DP 即可做到 \(O(n^2+Tn)\)。
根据大样例以及肉眼观察,最优情况下答案为 \(O(\sqrt n)\) 量级且好人获胜概率随坏人增多而减小。仅维护 \(j \leq 500\) 的 \(f_{i,j}\) 即可,复杂度 \(O(n \sqrt n + T \log n)\)。
Problem C. 龙神木仙人掌
题意:
给定一个 \(n \times n\) 可逆矩阵 \(A\),你需要执行 \(q\) 次操作。每次操作给定一个 \(n \times 1\) 的列向量 \(u\) 和一个 \(1 \times n\) 的行向量 \(v\),执行 \(A = A - uv\),并求出得到的矩阵的逆。为减小输出量,你需要先将元素值的平方对 \(998244353\) 取模,再输出取模结果的和,但和不取模。如果得到的矩阵不可逆,则撤销此次操作并输出一行 You're wrong. Here's why.。
\(1 \leq n, q \leq 300\),\(2\) 秒,\(512\) MB。
解法:
无敌线性代数题。
根据题解,Sherman–Morrison–Woodbury 公式给出,若 \(1-vA^{-1}u \neq 0\),则 \((A-uv)^{-1}=A^{-1}+A^{-1}u(1 - vA^{-1}u)^{-1}vA^{-1}\)。只需要计算矩阵与向量相乘,直接计算即可,复杂度 \(O(n^3+qn^2)\)。
2025.1.2 GZOI 冬令营训练 #3
\(80+5+24=109\)。
Problem A. 未知
题意:
给定 \(n\) 和 \(q\) 以及 \(q\) 个限制,每个限制 \((op,l,r,v)\),其中 \(op \in \{0,1\}\)。考虑一个 \(1\) 到 \(n\) 的排列 \(p_1,p_2,\cdots,p_n\),要求对于每个限制,若 \(op=0\),则 \(\min \limits_{i=l}^r p_i = v\)。若 \(op=1\),则 \(\max \limits_{i=l}^r p_i = v\)。你需要给出某个合法的 \(p\) 或报告无解。
\(2 \leq n,q \leq 2 \times 10^4\),\(6\) 秒,\(1\) GB。
解法:
显然可以建立二分图模型,直接跑 Dinic 可以做到 \(O(n^{2.5})\),注意我们并不能显示建图,维护邻接矩阵是否存在以及每个点的匹配点即可算出容量。空间复杂度 \(O(n^2)\),但是使用的是 bool,所以空间上可以通过。时间上,适当卡常即可通过。赛时代码没有卡常,仅获得 \(80\) 分。
事实上,发现连边是若干区间状物,将建图换成分块优化建图可以做到 \(O(n^2)\),使用线段树优化建图也可通过,但复杂度可能是错的或不容易证明。
Problem B. 观光缆车
还不会,别急。
Problem C. 旅游
解法:
首先,\(A\leq B\) 时答案为 \(1\),这是很显然的,因为先手无论怎么走都会被后手拉回去。
考虑 \(A>B\)。
直接求答案看着就很丑,考虑先二分一手,变为判断最优策略下后手能否使得最终位置编号 \(\leq x\)。将 \(\leq x\) 的点的点权设为 \(0\),其他设为 \(1\)。仅有 \(01\) 的问题应该是容易考虑的。
首先我们有一个朴素 DP,记 \(f_i\) 表示现在在点 \(i\),子树外的边都被走过,最优策略下最终会落到 \(0\) 还是 \(1\)。转移枚举子树内到 \(i\) 距离为 \(A\) 的点 \(j\) 和距离 \(j\) 为 \(B\) 的点 \(k\),但发现此时我们可能需要求形如一个点子树去掉某个儿子的子树的答案。对这个也转移一下可以做到 \(O(n^3)\)。
我们考虑更好的进行状态描述。记 \(f_i,h_i,g_i\) 表示 \(i\) 子树,先手先走的结果,现在在 \(i\) 的父亲,且 \(i\) 子树被删去,先手先走的结果,以及 \(i\) 子树,后手先走的结果。
首先我们忽略复杂度,考虑转移的过程,发现 \(f\) 和 \(h\) 都是子树内枚举点转移,但是 \(g\) 似乎要考虑邻域内的点,转移看似构成环,但是注意到 \(A>B\),仔细分析发现并不存在环,并且可以对转移按照权值排序。具体地,对于更新 \(f_u\),权值为 \(dep_u\),更新 \(h_u\),权值为 \(dep_u-1\),更新 \(g_u\),权值为 \(dep_u-B\)。按照权值大到小排序更新 DP 即可。
考虑转移的细节。我们发现由于 \(A\) 固定,\(f\) 的转移中枚举距离为 \(A\) 的点复杂度均摊正确,转移 \(h\) 的时候不能枚举父亲子树内距离为 \(A\) 的点,这样显然可以被菊花卡爆。但是只需要更新 \(g\) 后算一下 \(A\) 级祖先的贡献即可。于是转移 \(h\) 复杂度也可以得到保证。问题在于转移 \(g\)。首先直接使用点分树维护邻域应该可行,但复杂度为 \(O(n\log^2n)\),加上二分要三个 \(\log\),不太能过。我们考虑暴力中,我们转移 \(g_u\) 时,枚举某个点 \(x\) 使得 \(x\) 在 \(u\) 的 \(B\) 级邻域内,然后从 \(f_x\) 或者 \(h_{son_x}\) 转移,由于 \(B<A\),可以发现 \(\operatorname{LCA}(u,x)\) 必然在 \(u\) 到 \(u\) 的 \(A\) 级祖先构成的链上。DP 过程中容易对于每个点 \(u\) 处理出子树内离他最近的 \(f_x=0\) 的 \(x\) 的深度,记为 \(r_u\)。那么事实上对 \(g\) 的转移仅需要维护单点修改与求链 \(\min\)。
问题似乎已经简单了很多,但是单点修改链 \(\min\) 要么用树剖,复杂度还是不优,要么用 LCT 或全局平衡二叉树等常数比较大的科技,这也不是我们想要的。但是我们发现按照权值排序的 DP 中,我们并不需要维护链 \(\min\)。每次更新 \(r_u\) 时直接做子树取 \(\min\) 即可。因为我们每次更新 \(g\) 时,其 \(B+1\) 级祖先由于权值大小关系必然还没被计算,所以这样做就是对的。只需要维护 DFN 序区间取 \(\min\),维护线段树即可。总复杂度 \(O(n\log^2n)\)。
线段树常数可能比较大,建议使用标记永久化而非下传标记。
2025.1.3 GZOI 冬令营训练 #4
\(100+100+0=200\)。
Problem A. 钓鱼
题意:
给定 \(n\) 和 \(n\) 个区间 \([l_i,r_i]\),求字典序最小的 \(1\) 到 \(n\) 的排列 \(p_1,p_2,\cdots,p_n\),使得对于所有 \(1 \leq i \leq n\),存在 \(j \in [l_i,r_i]\) 且 \(p_j = i\)。
\(1 \leq n \leq 2 \times 10^5\),\(2\) 秒。
解法:
属于是套路题。
要求字典序最小的序列,常见做法是按位填数,然后判定后缀是否有可行方案。
假设我们现在要确定排列的第 \(i\) 个数,即我们已经填完了 \(p_1,p_2,\cdots,p_{i-1}\),后面的数都还没确定。填完 \(p_i\) 后,如果我们记 \(c_j\) 表示有多少个 \(r_x \leq j\) 的限制还未被满足,则显然有解的必要条件是对于所有 \(j \geq i\),都有 \(c_j \leq j - i\),因为我们之后最多填 \(j-i\) 种不同的数。
另一方面,整个问题可以变为一个二分图匹配模型,故每次填 \(p_i\) 后都有这个条件成立等价于有解。
类似扫描线,我们依次填入时维护所有 \(c_j\),我们要支持区间加减 \(1\),维护全局最小值和其位置。在填完后若 \(c_j<0\),则我们需要找到最小的 \(x\) 使得 \(x\) 还未被填过且 \(r_x \leq j\),维护另一棵线段树并在线段树上二分即可。复杂度 \(O(n \log n)\)。
Problem B. 挖野菜
题意:
给定小写英文字符串 \(s,t\),设其长度分别为 \(n,m\)。求有多少有序对 \((x,y)\),使得 \(1 \leq x, y \leq n\),且 \(s[1 \dots x] + s[n-y+1\dots y]\) 是 \(t\) 的子串,即有多少 \(s\) 的前缀与后缀拼接结果是 \(t\) 的子串。
多测,\(T \leq 8\),\(1 \leq n, m \leq 2 \times 10^5\),\(3\) 秒,\(512\) MB。
解法:
直接想法是考虑枚举 \(t\) 的子串的分割点,但这样每个 \((x,y)\) 会被多次计算。
我们考虑字符串 \(s+x+t+y+s\),其中 \(x,y\) 是两个不同的非小写英文字符。现在我们对这个串正反分别做一次 KMP,并且我们枚举 \(y\)。根据第二次 KMP 得到的失配树,\(t\) 中 \(s[n - y + 1\dots n]\) 的出现位置是一个子树,我们考虑这个子树内的所有位置,其对应的可能的 \(x\) 是第一次 KMP 得到的失配树的一条到根链上对应的位置,我们只需要求出子树内这些点到根的路径并大小即可。
点集到根路径并是经典套路,按照 DFN 排序后相邻求 LCA 即可。我们直接对第二棵树做启发式合并,使用 set 维护点集在 DFN 序下排序的结果即可。这样的复杂度是 \(O(n \log^2 n)\) 的,注意到这是树上启发式合并,常数比较小,已经可以通过了。赛时我写的就是这个做法。
事实上,我们考虑用线段树合并替代启发式合并,并维护一个 \(O(n \log n)-O(1)\) 的树上 LCA 就可以直接做到 \(O(n \log n)\) 了。
Problem C. 单独行动
题意:
给定一个 \(n\) 个点 \(m\) 条边的无向简单图,考虑对于这张无向图构建一张点数相同的有向图,其中每条边 \((u_i,v_i)\) 有 \(\dfrac{1}{3}\) 的概率从 \(u_i\) 指向 \(v_i\),有 \(\dfrac{1}{3}\) 的概率从 \(v_i\) 指向 \(u_i\),还有 \(\dfrac{1}{3}\) 的概率被删去。求此有向图为 DAG 的概率,答案对 \(10^9+7\) 取模。
\(1 \leq n \leq 20\),\(0 \leq m \leq \dfrac{n \times (n-1)}{2}\)。
解法:
先将概率转为方案数。
DAG 计数相关,我们先考虑朴素状压 DP。
记 \(f_S\) 表示点集 \(S\) 的导出子图为 DAG 的方案数。转移是经典的容斥,或者叫子集反演。枚举导出子图中出度为 \(0\) 的集合的子集 \(T\),\(f_S = \sum \limits_{T \subseteq S, T \neq \varnothing} f_{S \setminus T \times 2^{E(S \setminus T,T)} \times (-1)^{|T|-1}}\)。其中 \(E(A,B)\) 为无向图边横跨 \(A\) 与 \(B\) 的边数量。直接 DP 即可做到 \(O(3^nn)\),无法通过。
我们注意到 \(E(S\setminus T,T)=E(S)-E(S\setminus T)-E(T)\),其中 \(E(A)\) 表示在点 \(A\) 中的边数。我们令 \(g_S = \dfrac{f_S}{2^{E(S)}}\),发现 \(g_S\) 是一个半在线子集卷积状物,直接按照集合大小枚举 \(s\) 并维护 FWT 结果即可。复杂度 \(O(n^22^n)\),可以通过。
2025.1.5 GZOI 冬令营训练 #5
Problem A. 简单的递归
题意:
给定 \(n,k,t\)。
定义 \(g(x)=k\times \varphi(x)\)。
求 \(g^t(n)\) 对 \(998244353\) 取模的结果,\(g^t(x)\) 表示 \(g(x)\) 复合 \(t\) 次。
\(1 \leq n,k,t < 998244353\)。
解法:
我们先考虑怎么暴力做,注意到过程中没有加法,直接维护答案的质因数分解形式即可。
进一步,观察可得存在 \(B\) 使得 \(g^t(n)\) 在 \(t \geq B\) 后的序列构成等比数列,其中 \(B\) 大概是 \(2 \log n\) 量级,原因是复合过程中因子会不断被消去。取 \(B=100\) 可以通过。
Problem B. 简单的线性代数
不会。
Problem C. 简单的字符串
不会。
2025.1.6 GZOI 冬令营训练 #6
Problem A. 随机游走
题意:
给定一个 \(n\) 个点的有向图。有 \(m\) 个人在图上随机游走。\(t_i\) 时刻,第 \(i\) 个人出现在 \(v_i\) 节点上。如果一个人在 \(t\) 时刻站在 \(u\) 点,设 \(S\) 为所有 \(u\) 通过一条边能到的点的集合(包括 \(u\) 自身),那么 \(t+1\) 时刻他会从 \(S\) 中等概率随机一个点走过去。走路不花费时间。
令 \(f(t)\) 表示 \(t\) 时刻在 \(n\) 节点的人期望个数对 \(10^9 + 7\) 取模的结果。给定 \(T\),你需要输出 \(f(1) \oplus f(2) \oplus \cdots \oplus f(T)\),其中 \(\oplus\) 指按位异或运算。
\(1 \leq n \leq 70\),\(1 \leq m \leq 10^4\),\(1 \leq T \leq 2 \times 10^6\),\(1 \leq t_1 < t_2 < \cdots < t_m \leq T\),\(1 \leq v_i \leq n\)。\(2\) 秒。
解法:
首先我们有一个朴素的 \(O(Tn^2)\) 的 DP,不能通过。
\(n\) 比较小,我们猜测是矩阵快速幂状物,但是我们要求每个时刻的 \(f\) 值的异或,所以并不容易直接用矩阵刻画。
考虑分块。我们设块长为 \(B\)。预处理转移矩阵的 \(1\) 到 \(B\) 次方。枚举时刻 \(i\) 从 \(1\) 到 \(T\),记录上一次我们计算答案的时刻 \(x\)。若 \(i-x<B\),由于我们只需要求 \(i\) 时刻在 \(n\) 节点的期望人数,所以本质上我么只需要求向量乘矩阵的第 \(n\) 行第 \(1\) 列的值,这个可以 \(O(n)\) 计算。如果 \(i-x=B\),或者 \(i\) 是一个关键点,那么我们直接把向量乘以矩阵更新,并令 \(x \gets i\)。取 \(B=n\),容易分析复杂度为 \(O(n^4+Tn+mn^2)\),可以通过。
取 \(B = \sqrt{\dfrac{T}{n}}\) 可以得到理论最优复杂度,但是由于复杂度瓶颈在于 \(O(Tn)\),所以并无太大差别。
Problem B. 钥匙问题
原题:P7110 晚秋绝诗。
解法:
首先可以注意到,如果存在一个区间 \([l,r]\),使得 \(l-1\) 与 \(r+1\) 的结果已知,且 \([l,r]\) 中每个数都是相邻两个的平均数,那么整个区间都已知。
更具体的,若区间 \([l,r]\) 满足区间内都是相邻平均数,且 \([l-1,r+1]\) 中至少有 \(2\) 个已知,那么 \([l-1,r+1]\) 均已知。
考虑暴力怎么做,我们将序列按照是否为平均数分段,且每个极长段 \([l,r]\) 都满足 \((l,r)\) 中每个数都为相邻平均数,且 \(l\) 与 \(r\) 并不是相邻平均数。
询问 \(x\) 时,先判掉初始已知 \(x\),那么假设 \(x \in [l,r]\),即 \(x\) 属于极长段 \([l,r]\) 中,若 \([l,r]\) 已知至少两个,那么是容易的。否则考虑其必须是左侧或者右侧过来的。找到左侧和右侧最近的区间内至少有两个已知的位置并讨论一下即可。
于是我们将所有极长段 \([l,r]\) 分为五种:
- \([l,r]\) 中至少有两个已知位置。
- \([l,r]\) 中有且仅有一个已知位置,且其为 \(l\)。
- \([l,r]\) 中有且仅有一个已知位置,且其为 \(r\)。
- \([l,r]\) 中有且仅有一个已知位置,且其不为 \(l\) 或 \(r\)。
- \([l,r]\) 中没有任何一个已知位置。
我们使用五个 set 维护所有区间,同时维护一棵树状数组用于查询每个区间中已知位置数量。进行一些分类讨论就可以通过此题。具体地,需要考虑每次询问的区间的类型,以及修改所影响的区间分裂或合并。细节比较多,但想清楚的话应该比较好写,代码中有很多部分是类似的。
Problem C. 最长公共子序列
原题:QOJ7309。
解法:
我们直接进行 DP。
记 \(f_{i,j}\) 表示第一个序列前 \(i\) 段和第二个序列前 \(j\) 段的 LCS。转移时,若 \(c_i = d_j\),枚举 \(i'<i,j'<j\),从 \(f_{i',j'}+k\) 转移,\(k\) 是这两段中 \(c_i\) 的出现次数最小值。直接转移为 \(O(n^4)\)。注意到我们可以同时移动指针 \(i',j'\),具体地,每次将两段中出现次数较小的往前移,复杂度 \(O(n^3)\),可以通过本题数据和原题所有数据。
进一步,转移是二维矩阵 \(\max\) 形式,可以做到 \(O(n^2 \log^2 n)\),进一步分析转移可以做到 \(O(n^2 \log n)\),不过我还不会。
2025.1.8 GZOI 冬令营训练 #7
Problem A. 罗盘
题意:
给定 \(n\),构造任意一个大小最大的集合 \(S\) 使得 \(S \subseteq \{1,2,\cdots,n\}\) 且 \(\forall x, y \in S, x \oplus y \notin S\)。
\(1 \leq n \leq 10^6\)。
解法:
记 \(f_n\) 表示最大的集合大小。
不难对较小的 \(n\) 打表,可以发现如下规律:
- \(f_1=1\)。
- \(f_2=2\)。
- \(f_{2n+1}=2f_n\)。
- \(f_{2n}=f_n+f_{n-1}\)。
进一步观察小数据的构造可以发现必然存在一种构造是连续一段,且段的开头也是可以直接找出规律的,于是就做完了。
Problem B. 树上睡觉
题意:
有一棵点数为 \(n\) 的树,根为 \(1\),每个叶子节点深度相同,对于每个点 \(2 \leq i \leq n\),\(fa_i < i\)。你有一个初始是 \(0\) 的能量值 \(S\)。你现在会在树上移动。
你有 \(m\) 种跳跃姿势,第 \(i\) 种跳跃姿势可以用一个正整数 \(b_i\) 表示。
假如你现在在节点 \(u\),每一时刻你可以做以下事情之一:
-
当 \(u\) 不是叶子节点,你可以睡一觉,并掉落到节点 \(p_u\),能量值变为 \(S+1\)。保证 \(p_u\) 是 \(u\) 的儿子节点。
-
当 \(S > 0\),你可以选择一个跳跃姿势 \(k (1 \leq k \leq m)\) 并向上跳 \(b_k\) 步,即走到 \(u\) 的 \(b_k\) 级祖先,能量值变为 \(S-1\)。你需要保证 \(b_k\) 级祖先存在。
定义 \(dis(u, v)\) 表示从 \(u\) 开始,初始 \(S\) 等于 0,走到 \(v\) 用时最短是多少。特别地,若 \(u\) 无法到达 \(v\) 则 \(dis(u, v) = 0\)。
求 \(\sum \limits_{u=1}^n\sum\limits_{v=1}^n dis(u, v)\)。
\(1 \leq n \leq 2 \times 10^5\),\(3\) 秒。
解法:
注意到给定的本质上是一棵树的剖分,我们使用轻重链剖分的名词来描述这个剖分。
我们先考虑暴力。
容易发现我们可以每次花两单位时间选择 \(k\) 并向上跳 \(b_k - 1\) 步。不难发现这是不劣的。
若我们想从 \(u\) 走到 \(v\),设 \(\operatorname{LCA}(u,v)=L\),那么必然是先从 \(u\) 走到 \(L\) 的祖先,然后落到 \(v\)。
记一个 DP,\(f_i\) 表示一个点需要向上 \(i\) 步所需要的最小时间。转移是朴素的背包。那么我们可以发现有 \(dis(u,v) = \min \limits_{d \leq k} f_k+dep_v-(dep_u-k)\) 之类的状物,但是我们发现如果某一步一次跳跃无论如何都会跳到 \(L\) 重链顶端之上,那么是不符合要求的。所以我们要对 \(b\) 小到大排序记录每个前缀的 DP 结果。这样我们可以枚举 \(u,L\) 做到 \(O(n^2)\),实测数据不太强,这样做获得了 \(70\) 分。
进一步,所有叶子节点深度相同,所以剖分必然为长链剖分。我们枚举 \(L\) 并考虑几种情况分类讨论,精细实现就可以做到 \(O(nm+n\sqrt n)\)。
Problem C. IMAWANOKIWA
不会。

浙公网安备 33010602011771号