集省轮二东山6202
我说我还在贺Wei_Han的题解
不过是不是应该写点不一样的,老抄别人题解不太合适。
那我先写一下补集的题解。
Wei_Han /bx
哦vscode写markdown这么方便吗?我已经难受地写了半天了((
怎么这么多题。。。
Day 1
T1 最优化题(maximize)
场切了。
T2 数数题(counting)
给定长度为 \(n\) 的整数序列 \(a\),可以进行任意次(可以是 \(0\) 次)以下操作:
- 选择一个区间 \([l, r]\),计算 \(v = \max\limits_{i=l}^{r} a_i\),然后 \(\forall i \in [l, r], a_i \leftarrow v\)。
设最终得到整数序列 \(b\),求有多少种不同的可能的 \(b\),答案对 \(998244353\) 取模。
\(n \le 10^5\)
首先我们知道颜色之间的顺序肯定不可能交换了,然后颜色有一个覆盖范围。
然后我们直接dp就能过掉排列了(到哪个位置,现在是哪个颜色)。
不是排列有个问题,可能一个最终排列有多种覆盖方式。
我们可以发现,如果两个相同颜色的覆盖区间有交,那么他俩必定重合。
那我们就优先让靠前的往后覆盖。dp的时候减掉由前面一个相同颜色覆盖的方案即可。
T3 计算几何题(geometry)
给定周长为 360 的圆环,每次你可以沿着直径或半径切一刀。若干次切割之后圆环会变成若干段圆弧,设弧长构成的可重集为 \(P\),要求 \(P\) 必须包含输入的大小为 \(n\) 的可重集 \(Q\) 作为子集。保证可重集 \(Q\) 只包含整数。
注意可重集 \(Q\) 是可重集 \(P\) 的子集的定义是:\(\forall v \in \mathbb{R}\),\(Q\) 中 \(v\) 的出现次数不超过 \(P\) 中 \(v\) 的出现次数。
\(1 \le n \le 16,\ 1 \le q_i \le 360,\ \sum_{i=1}^{n} q_i \le 360\)
考场上把 \(\sum q_i=360\) 过了。
其实很接近了啊。
\(n\) 很小,考虑状压。
一种情况是所有的都拿半径切,其他情况至少有一条直径,那可以考虑从这条直径开始,从直径的两边逆时针填,如果两边填的一样多,就拿一条直径填。

但是如果 \(\sum q_i \not = 360\) 中间可能空一段再填。
考虑一个方案,把所有匹配的部分全部排在前面,如果空部分也能匹配那就把他放在尽量靠后的位置。
感觉说不明白。。。
反正看代码就是了。。
Day 2
T1 最优化问题(optimize)
有 \(n\) 种类型的男生和 \(2n\) 个女生。男生的类型用从 \(1\) 到 \(n\) 的整数编号,而女生用从 \(1\) 到 \(2n\) 的整数编号。
第 \(i\) 种类型的男生有 \(c_i\) 个,这 \(c_i\) 个男生中的每一个都喜欢编号为 \(a_i\) 和 \(b_i\) 的女生。
求一个最大的男生集合的大小,使得对于该集合中的任意两个男生,至少存在一个女生被他们两人都喜欢。
多组测试数据
\(T \le 500,n \le 10^7,c_i \le 10^9\)
你们咋都这么牛?你们咋都这么牛?你们咋都这么牛?
我咋这么菜?我咋这么菜?我咋这么菜?
你知道过了半场发现最开始的结论假了的救赎感吗???绝望了哥们啊。
考虑要么选一个点的邻域,要么选一个三元环。
感觉一点也不好做吧???

设 \(a>b>c\),我们把三元环放在 \(a,b\) 边中间的点,设这个点为点 \(C\) 统计,考虑选三元环当且仅当 \(c>N(C)-a-b\),我们发现只有 \(a,b\) 边是 \(N(C)\) 中最大的两条边才有用,不然由 \(a>b>c\) 且 \(N(C)\) 中有边权值 \(>b\),则选邻域一定比选三元环优。
我好菜啊。
T2 构造题(construct)
给定一个包含 \(n\) 个整数的数组 \(a\)。每次操作中,你可以选择一个位置 \(i\ (1 \le i \le n)\),将 \(a_i\) 减少 \(k\),同时将所有数据元素 \(a_j\ (1 \le j \le n, j \ne i)\) 增加 \(t\)。
求将数组中所有元素变为非正数(即小于或等于零)所需的最少操作次数。如果无法实现,则报告该情况。
\(n \le 10^6,k,t \le 10^9,-10^{18} \le a_i \le 10^9\)
感觉巨难写啊。完全不想写啊。那咋办还是得写啊。
先判掉不需要操作的情况。
以下令 \(k=k+t\),问题变为全局 \(+t\),单点 \(-k\)
考虑如果 \(nt<=k\) 那么考虑若 \(x\) 次操作合法,\(x+n\) 次操作一定也合法。只要把所有的位置全操作一遍即可。
先把这种情况处理掉,枚举操作次数 \(\bmod n\),判断所有位置在加了这么多次 \(t\) 之后,需要减掉多少次。
即求 \(\sum_i \lceil \frac{a_i+t\times mid}{k} \rceil\),这个二分一下最后一个需要操作的 \(a_i\),主席树处理一下取模。
现在复杂度不太正确,\(O(n\log V \log k)\)。
那你考虑把枚举的这 \(n\) 个模数 shuffle 一下,先check一下能不能成功贡献答案,期望更新 \(\log n\) 次答案。
然后还要考虑 \(nt>k\) 的情况,首先若 \(a_i>a_j\) 那么 \(i\) 的操作次数一定不小于 \(j\)。然后显然不能 \(n\) 个位置都操作,否则全不操作更优,那你此时对前 \(n-1\) 求出答案,check一下 \(n\) 就好。迭代一下,直到 \(nt<=k\)。
T3 判定问题(check)
给定一个无限大的二维网格,其中每个单元格要么是空的,要么是被阻挡的。
在网格中,你可以向上、下、左或右移动到相邻的非阻挡单元格。
在四处走动了一会儿后,你注意到被阻挡单元格的模式是周期性的。更准确地说,有一个 \(R \times C\) 的模式在无限重复。具体形式请参见下图。

你需要求解 \(Q\) 个询问,每个询问给定 \(s_x, s_y, t_x, t_y\),问:单元格 \((s_x, s_y)\) 是否能不经过阻挡的走到单元格 \((t_x, t_y)\)?
\(R,C \le 1000,Q \le 10^5,s_x,s_y,t_x,t_y \le 10^{12}\)
首先应该容易想到基(线性组合,不考虑线性的具体次数,基可以很优美的刻画)。虽然我没想到。
那两个点首先得在一个联通块,随便选一个点当根,一个联通块就是一棵树,然后对于联通块的每个点算出来一种到根的方式 \(dis[x][y]=\{delta_x,delta_y\}\) ,考虑所有移动的方式,和树边能形成若干个环,把这些环加入基里,看能不能把查询的向量消成0
如果你学过一点向量的知识,学过一点数论,那你应该知道一个基应该包括两个向量 \((x,y),(0,y')\) 加入一个新的向量先和第一个的 \(x\) 辗转相除一下,然后消成0之后再和第二个向量的 \(y'\) 辗转相除一下。
CF908H New Year and Boolean Bridges
ARC132F Takahashi The Strongest
P9316 [EGOI 2021] Double Move
UOJ310 【UNR 2】黎明前的巧克力
给定一个长度为 \(n\) 的序列 \(a\),每个元素 \(a_i\) 有 3 种分配方式:
- 给 \(A\)
- 给 \(B\)
- 谁也不给
要求最终给 \(A\) 的所有元素的权值异或和等于给 \(B\) 的所有元素的权值异或和(没被分配任何数,则异或和为 \(0\)),求分配方案数。
\(1 \leq n \leq 10^6,\ 0 \leq a_i \leq 10^6\)。
发现给 A 和给 B 其实是一致的,然后就是求 \([z^0]\prod(1+2z^{a_i})\)。
可以对每个式子求个FWT然后乘起来,因为式子只有两项,我们先手动算一下FWT之后的数组是什么形式。
手算一下可以发现 \(|S\&a_i|\) 为偶数的位置FWT之后为3,奇数的位置为-1.
那现在我们考虑最终乘出来的FWT数组又长什么样子,就需要考虑每个位置乘了多少次3,多少次-1.就是求有多少个 \(a_i\) 满足 \(|S\&a_i|\) 为奇数,发现总共 \(a_i\) 个数为 \(n\),那你直接对 \(b_S=a.count(S)\) 求 \(FWT\),每个位置存的就是偶数个数-奇数个数,两个方程解一下就行。
其实这个 \(b\) 应该有很多种取法吧,只是直接这么取比较简单。
我们要求的如果是 \(\prod(b_i + c_i z^{a_i})[z^0]\) 呢?\(O(n + v \log^2 v)\)? \(O(n + v \log v)\)?
\(\log^2\) 可以把同位置合并一下,然后分治 \(FFT\) 嗯乘一下就行。
单 \(\log\) 好像放线段树上分别维护一下乘了奇数次和偶数次就行。
P5577 算力训练
Day 3
T1 排列题(permutation)
你有 \(n\) 个木块,它们共有 \(k\) 种不同的颜色,排成一行。木块的颜色依次为 \(c_1, c_2, \dots, c_n\),所有颜色均在 \(1\) 到 \(k\) 之间。
如果某种颜色的所有木块所处位置的平均值等于 \((n+1)/2\),则称该颜色是平衡的。注意这个数值未必是整数。

你能否将这些木块重新排列,使得所有颜色都平衡?
\(\sum n \le 2e5\)
我真服了考场上把两个想到的思路拼一块就可以了。最后打了个搜也啥都没看出来。
同样写了半场发现结论假了。
首先发现偶数可以直接左右放,奇数可以转化成3和偶数情况。
首先取一个放在中间。考虑较小的情况。
考虑两个,分别是相交和包含情况,你惊奇地发现正好能对上。然后扩展一下就对了。我怎么两种都画出来了,考场上没想到拼一下。

T2 数数题(count)
对于一个正整数序列 \(a\),定义其最大权独立集的权值为从 \(a\) 中选择若干不相邻的数,选出的数的和的最大值。
如果 \(a\) 的最大权独立集权值恰好是 \(a\) 所有数的和的一半,则称 \(a\) 是坏的,否则称 \(a\) 是好的。
若正整数序列 \(a\) 的任何子区间都是好的,则称 \(a\) 是极好的。
给定 \(n,m\) 和 \(n\) 个正整数集合 \(A_1, \dots, A_n\),\(n\) 表示 \(a\) 的长度,集合中的数都 \(\in [1,m]\)。问:若 \(a_i \in A_i\),则有多少个序列 \(a\) 是极好的。
答案对 \(998244353\) 取模。
\(n \le 200,m \le 19\)
好像没空写了。
T3 最短路问题(shortest)
图中有 \(n\) 栋建筑,从 \(0\) 到 \(n-1\) 编号,还有 \(m\) 座天桥,从 \(0\) 到 \(m-1\) 编号。这张规划图绘制在一张二维平面上,其中建筑和天桥分别是垂直和水平的线段。
第 \(i\) 栋建筑的底部坐落在坐标 \((x[i], 0)\) 上,建筑的高度为 \(h[i]\)。因此,它对应一条连接点 \((x[i], 0)\) 和 \((x[i], h[i])\) 的线段。
第 \(j\) 座天桥的两端分别在第 \(l[j]\) 栋建筑和第 \(r[j]\) 栋建筑上,并具有正的 \(y\) 坐标 \(y[j]\)。因此,它对应一条连接点 \((x[l[j]], y[j])\) 和 \((x[r[j]], y[j])\) 的线段。
称某座天桥和某栋建筑相交,如果它们有某个公共的点。因此,一座天桥在它的两个端点处与两栋建筑相交,同时还可能在中间和其他建筑相交。
你想要找出从第 \(s\) 栋建筑的底部到第 \(t\) 栋建筑的底部的最短路径长度,或者确认这样的路径不存在。在这里行人只能沿着建筑和天桥行走,并且不允许在地面上行走,也就是说不允许沿着 \(y\) 坐标为 \(0\) 的水平线行走。
行人能够在任意交点从某座天桥走进某栋建筑,或者从某栋建筑走上某座天桥。如果两座天桥的端点之一在同一点上,行人也可以从其中一座天桥走上另一座天桥。
对于所有数据,满足 \(1 \le n,m \le 10^5\),\(0 \le x[0] < x[1] < \dots < x[n-1] \le 10^9\);\(1 \le h[i] \le 10^9\),\(0 \le l[j] \le r[j] \le n-1\),\(1 \le y[j] \le \min(h[l[j]], h[r[j]])\),\(0 \le s,t \le n-1\),\(s \ne t\)。除在端点处外,任意两座天桥不会有其他公共的点。
怎么还有IOI题。
我觉得这题Wei_Han的题解就很好啊,但是我还是乱写一通吧,毕竟以后大概率还是会看自己的题解。
先考虑如果S=1,T=n,那肯定不可能走回头路对吧。
那我们发现一件事情,如果现在在一个较高的桥上,他到头之后,底下的桥都是可以选的,但是你一个较低的桥走着走着可能就上不去了对吧!
所以我们发现如果要上桥那肯定尽量早上桥,每个桥保留左右端点及端点下面一个位置。
如果没有这个特殊性质,那可能就要往回跑了,那往回跑肯定也是为了上桥,那再记录每个桥离S,T最近的上桥点,跑最短路即可。
P4747 [CERC2017] Intrinsic Interval
AGC061D Almost Multiplication Table
ARC184B 123 Set
QOJ4217 Graph Coloring
QOJ4218 Hidden Graph
P5115 Check,Check,Check one two!
P4118
Day 4
T1 莫队之理(ds)
随机生成 \(q\) 个 \([1,n]\) 范围内的区间,问只使用加位置和清空操作,如何在保证加位置和清空操作不超过给定限制的情况下,凑出 \(q\) 个区间每个区间至少一次,需要给出加和清空的具体方案。
\(n \le 5e4,q \le 1e5\)
加操作次数要求 \(\le 6e7\),清空次数 \(\le n\).
考场上感觉做法很优,瞎写过了。
证明应该是按照l排序,r的lis长度期望是根号。
T2 又见星图(starmap)
一个星座可以看成一个由 \(n \times m\) 颗恒星构成的矩形,其中坐标 \((i,j)\) 处有一颗亮度为 \(a_{i,j}\) 的恒星。坐标为 \((r,c)\) 的恒星是这个星座的中心。
用 \(d_{i,j}\) 表示坐标 \((i,j)\) 处的恒星到星座中心的曼哈顿距离,即
称一个星座构成一个星图,当且仅当距离星座中心越近的恒星亮度越高,即满足:
- 对于任意两个位置 \((i,j)\) 和 \((i',j')\),若 \(d_{i,j} \le d_{i',j'}\),则有 \(a_{i,j} \ge a_{i',j'}\)。
你作为神的存在,可以对这个星座进行若干次修改,从而让其形成一个星图。具体来说,你每次可以在下面两种操作中选择一种:
- 选择四个整数 \(i,l,r,v\),然后对所有 \(j = l,l+1,\dots,r\),令
- 选择四个整数 \(i,l,r,v\),然后对所有 \(j = l,l+1,\dots,r\),令
请你求出,最少需要多少次操作,才能将该星座修改成一个星图。
对于全部数据,\(1 \le n,m < 160,\ 1 \le r \le n,\ 1 \le c \le m,\ a_{ij}\)
我咋这么菜我咋这么菜。
网络流+dp题。
先考虑 \(r=c=1\) 的情况,那我们dp考虑现在是什么颜色,覆盖了哪一段,那我们当然知道有哪些点要修改,修改一定是一行或者一列,二分图匹配一下。
其他情况就是多拆几个点,颜色一定是当前范围内最小颜色,然后图是增量的,没了。
T3 最后的登山(climb)
不想订了。
P5451 [THUPC 2018] 密码学第三次小作业
现在有两个用户由于巧合,拥有了相同的模数 \(N\),但是私钥不同。设两个用户的公钥分别为 \(e_1\) 和 \(e_2\),且两者互质。明文消息为 \(m\),密文分别为:
现在,一个攻击者截获了 \(c_1\),\(c_2\),\(e_1\),\(e_2\),\(N\),请帮助他恢复出明文 \(m\)。
\(1 \le T \le 10^4\), \(2^8 < N < 2^{63}\),\(N\) 有且仅有两个素因子,其余数据严格按照上述RSA算法生成。
真无敌了这题
\(m=m^1=m^{e_1x+e_2y}=c_1^x c_2^y\)
要求逆元就求一下逆元。
Day 5
T1 小根堆(heap)
给定一个由 \(n\) 个 + 和 \(m\) 个 - 组成、长度为 \(n+m\) 的字符串 \(s\),以及一个由 \(m\) 个整数组成的集合
请准备两个集合 \(X = \emptyset\)、\(Y = \emptyset\),并按照 \(i = 1, 2, \dots, n+m\) 的顺序依次执行以下操作:
- 当 \(s\) 的第 \(i\) 个字符为
+时,从 \(1\) 到 \(n\) 的整数中,选择一个既不在 \(X\) 中、也不在 \(Y\) 中的整数,加入集合 \(X\)。 - 当 \(s\) 的第 \(i\) 个字符为
-时,从 \(X\) 中取出最小的整数 \(x\),将其从 \(X\) 中删除,并加入集合 \(Y\)。根据约束条件,进行该操作前 \(X\) 一定非空。
对于向 \(X\) 中加入整数的顺序,共有 \(n!\) 种可能。问其中有多少种顺序能够使得所有操作完成后 \(Y = a\)。请输出这个方案数对 \(998244353\) 取模的结果。
对于全部数据,\(1 \le m \le n \le 500\),\(s\) 是一个由 \(n\) 个 + 和 \(m\) 个 - 组成、长度为 \(n+m\) 的字符串,并且对于任意 \(i=1,2,\dots,n+m\),在 \(s\) 的前 \(i\) 个字符中,- 的数量不超过 + 的数量;同时满足 \(1 \le a_1 < a_2 < \dots < a_m \le n\)。
考场上胡了一个巨大麻烦的做法,最后半小时才过,我真人才。
事实上下午给wfyz的俩同学讲我的做法,我惊奇地发现我好像已经不太会我的做法了!!!
(这下真的有0人会我考场的做法了)
一会去学一下简单一点的做法。
哦我好像会了,但是也没那么简单啊。建议洛谷题解第一篇。
大概流程就是要在脑子里模拟一个堆,然后对着这个堆凑性质。
对着-做,有一些+要和-配对,有一些没有配对。然后要给每个+分配一个数。我们把最终弹掉的数叫做-数,没弹掉的叫做+数。
首先你先观察一下,这些+-有啥性质
首先任意时刻,堆里的数一定形如(堆顶放在前面) ------+++++++
那么体现在比一个+数大的-数没弹完之前,+数不能放进堆里。放在序列上考虑就是,考虑-数的后缀最大值 \(v\),后面放了所有 \(<v\) 的+数。
这是+数和-数之间的限制。
还有的就是两个-数之间的限制,比他小的没弹掉之前不能弹他。
那你从后往前考虑,设 \(f\)
T2 刺杀(assassinate)
有一棵 \(n\) 个结点的树,第 \(i\) 条边连接结点 \(u_i\) 和 \(v_i\)。
你是一名刺客,初始时刻 \(0\) 位于结点 \(s\),需要前往结点 \(t\) 执行刺杀任务。每个时刻你可以选择:
- 停留在当前结点,等待任意非负实数时间;
- 移动,花费 \(d_i\) 的时间沿第 \(i\) 条边从一个端点走到另一个端点。移动过程中你始终处于这条边上,不能中途停下。
有一名守卫在树上循环巡逻。他的巡逻路线由 \(k\) 个结点 \(x_1, x_2, \dots, x_k\) 描述,守卫按照
的顺序不断循环移动。对于每一段 \(x_i \to x_{(i \bmod k)+1}\),守卫都沿树上的唯一路径行进,中途不会在任何结点停留。守卫通过第 \(j\) 条边所需的时间为 \(c_j\)。
冲突规则:如果在某个时刻,你和守卫同时出现在同一条边上(包括边的内部,但不包括端点),则刺杀任务失败。同时出现在某个结点上不算失败。
请你求出完成刺杀任务(即从 \(s\) 到达 \(t\))所需的最少时间。由于答案可能很大,请输出答案对 \(998244353\) 取模后的结果。如果无法完成任务,输出 \(-1\)。
- \(1 \le T \le 10\);
- \(2 \le n \le 2 \times 10^5,\ 2 \le k \le 2 \times 10^5\);
- \(1 \le u_i, v_i \le n\),输入保证这些边构成一棵树;
- \(1 \le c_i, d_i \le 10^8\);
- \(1 \le x_i \le n\),且 \(x_i \neq x_{(i \bmod k)+1}\);
- \(1 \le s, t \le n,\ s \neq t\);
- 在同一个测试点中,所有测试数据的 \(\sum n\) 和 \(\sum k\) 均不超过 \(2 \times 10^5\)。
有那么简单吗我真服了
好像题解确实也写不了多少字。
只把 S-T 的链拉出来,那就是,每次能走的时候立即走,走不了的时候就等待。
对 S-T 的链做扫描线,对时间建数据结构,每次覆盖一段区间,查询空位置 \(\ge d_i\) 最靠前的位置。
覆盖有从一个时间点向前覆盖的,有从一个时间点向后覆盖的(守卫从儿子到父亲还是从父亲到儿子)。随着扫描线的移动,这些覆盖的位置也有移动,黄的往后移动,蓝的往前移动,这看起来爆炸了是吧。
不过你先别急,你发现一个非常优美的性质,两种颜色一定交替出现并且不交,那你维护一下黄蓝最近距离和蓝黄最近距离,看起来就结束了对吧!!

我来研究一下这玩意怎么写。
哦非常好啊扫到同一位置长度也是一致的。
首先要拎出来S-T的链
然后求出来守卫所有覆盖的区间,从哪个位置到哪个位置,守卫第一次什么时候经过。守卫覆盖的状态也是重复的,那你只需要保留两个周期,从当前时刻出现的第一个位置往后找空段。
真难写吧。。。
写平衡树把。感觉线段树动态开点比较有道理,但是空间感觉很危险。
那你记录以s为基础的最靠前的时间,向上还是向下,子树内01,10段最大距离是多少。
OK我们把扫描线部分考虑完了,还有之前的部分,首先你要拎出链来。然后你要判断守卫这条路径和链交不交,交的话什么时候交,所以有什么LCA和求两点dis。
应该就没了吧。。
哦我好像会线段树了,那就是建2*k个节点,然后二分合并就可以了???
笑点解析,线段树区间查询递归到底也过了,我新交的那发应该复杂对对了吧???
T3 随机算法(random)
不想订了
Day 6
T1 股票劝说(stock)
场切了
T2 逃生游戏(escape)
小明正在打游戏。
这是一个逃亡游戏,地图里有 \(n\) 个补给站,由 \(n-1\) 条道路将这些补给站连通,故该地图形成了一棵树。游戏会选择地图一个叶子并将其标记为出口,小明将从 \(1\) 号补给站进入地图,并一路逃到出口去,中途不走回头路(不然还能叫逃亡游戏吗)。
每个补给站有一个强度为 \(x_i\) 的补给,每当小明经过一个补给站时,小明就可以选择进行补给或者忽略它。小明通过他多年的游玩经验得知,他必须在离开地图前恰好 \(k\) 个补给站进行补给(可以在出口补给站和入口补给站补给),才能顺利逃亡,补给少了会导致能量不够,而补给多了又会导致时间不够。但是,游戏有一个惩罚机制,如果小明在之前进行过一次补给,设其强度为 \(a\),则之后所有的补给强度都必须不大于 \(a\),若一个补给站的补给强度大于 \(a\),则小明不能在这个补给站补给。
为了提高难度,游戏不会在一开始告诉小明出口具体是哪个节点,而是在小明每次到达一个补给站并决定是否进行补给之后,告诉小明出口位于该补给站的哪个儿子方向(设 \(1\) 为根),这将让决策变得更加困难。不过好就好在,游戏一开始就会告诉小明所有的 \(x_i\),以供小明思考策略。小明的策略很简单:提前选好一些补给站,在经过其中的补给站时必定进行补给,并保证对于每个叶子作为出口的情况均能满足所有条件。容易发现这是所有确定性策略中的最优策略。
不出意外地,小明作为老玩家已经玩腻了,于是他开始追求数学上的乐趣。他想知道有多少种确定将要进行补给的补给站的方案,使得不管出口是哪个叶子,他都能稳定获胜。并且,他查阅代码得知,每个补给站的 \(x_i\) 是在游戏开始时选定的,其取值范围是 \([L_i, R_i] \cap \mathbb{Z}\)(选定后将会告诉小明),于是他想要你求出对于所有可能的地图局面,选取补给站集合方案的数量总和。
当然小明注意到在可以直接数学计算的一些情况中,方案数会是天文数字,于是他会让你输出其对 \(1004535809\) 取模后的结果。
对于 100% 的数据,\(1 \le n \le 200,\ 1 \le k \le 20,\ 1 \le L_i \le R_i \le 10^9\)。保证输入的图是一棵树。
拉插题啊。订题的时候嗯胡代码胡对了非常好啊。
首先要会一下拉插的板子
前半部分是简单的,你写出了这么一个dp
void dfs(int u,int fa) {
bool isleaf=true;
for(int i=head[u];i;i=nxt[i]) {
int v=to[i];
if(v==fa) continue;
isleaf=false;
dfs(v,u);
}
for(int j=0;j<=20;j++) for(int k=0;k<=2000;k++) g[j][k]=0;
if(isleaf) for(int k=0;k<=2000;k++) g[0][k]=1;
else
for(int j=0;j<=20;j++)
for(int k=0;k<=2000;k++) g[j][k]=1;
for(int i=head[u];i;i=nxt[i]) {
int v=to[i];
if(v==fa) continue;
for(int j=0;j<=20;j++)
for(int k=0;k<=2000;k++) g[j][k]=f[v][j][k]*g[j][k]%MOD;
}
for(int j=0;j<=20;j++) {
for(int k=0;k<=2000;k++) (f[u][j][k]+=1ll*g[j][k]*(R[u]-L[u]+1))%=MOD;
ll S=0;
for(int k=0;k<=2000&&j<20;k++) {
if(L[u]<=k&&k<=R[u]) (S+=g[j][k])%=MOD;
(f[u][j+1][k]+=S)%=MOD;
}
}
}
然后式子是显而易见的嘛,设 \(f[u][j][k]\) 为选了 \(j\) 次,不大于 \(k\) 的方案数。
\(f[u][j][k]=\prod_v f[v][j][k]+\sum_k[L[u] \le k \le R[u]] \prod_v f[v][j-1][k]\)
完就完在,\(k\) 这一维很大。然后就爆了对吧
我们先考虑 \(L[u] =1, R[u]=1e9\) 这玩意保证了后面的范围限制一定满足。我们对着这个分析一下次数。
对于叶子节点,我们知道
\(f[u][0][k]=R[u]-L[u]+1,f[u][1][k]=max(k-L[u]+1,0)\)
这是关于 \(k\) 的一次方程
然后分析一下其他节点
\(f[u][j][k]=\prod_v f[v][j][k]+\sum_k\prod_v f[v][j-1][k]\)
式子的前半部分显然不超过子树次数的和
考虑后半部分,相当于多项式连乘然后再对前 \(k\) 个点值求和,根据高中数学可以知道这个的次数不超过子树次数和+1.那么我们每进行一次合并次数最多+1,总的次数不超过 \(n\)。
现在我们考虑原问题,原问题考虑离散化,拆成若干段。从最小的段开始做,当我们处理完值域第 \(i\) 段,那么前 \(i-1\) 小的段可以视作定值。因此也是个多项式,次数也不超过 \(n\)。
剩下的看代码吧。
void dfs(int u,int fa) {
bool isleaf=true;
for(int i=head[u];i;i=nxt[i]) {
int v=to[i];
if(v==fa) continue;
isleaf=false;
dfs(v,u);
}
if(isleaf) {
for(int k=0;k<=n;k++) f[u][0][k]=R[u]-L[u]+1;
for(int k=0;k<=n;k++) f[u][1][k]=max(min(tl+k,R[u])-L[u]+1,0ll);
nsav[u][0]=R[u]-L[u]+1; nsav[u][1]=max(min(tr,R[u])-L[u]+1,0ll);
return ;
}
for(int j=0;j<=20;j++) for(int k=0;k<=n;k++) g[j][k]=0,g[j][k]=1;
ll mul[21];
for(int j=0;j<=20;j++) mul[j]=1;
for(int i=head[u];i;i=nxt[i]) {
int v=to[i];
if(v==fa) continue;
for(int j=0;j<=20;j++) for(int k=0;k<=n;k++) g[j][k]=f[v][j][k]*g[j][k]%MOD;
for(int j=0;j<=20;j++) mul[j]=mul[j]*sav[v][j]%MOD;
}
for(int j=0;j<=20;j++) {
for(int k=0;k<=n;k++) (f[u][j][k]+=g[j][k]*(R[u]-L[u]+1))%=MOD; //不选
if(j==20) break;//这一层选
ll S=(sav[u][j+1]-mul[j+1]*(R[u]-L[u]+1))%MOD; //你考虑后面的那个sum prod 的意义是,这一层选的方案数,这个式子算的就是值域范围<当前范围且u被选的方案数
for(int k=0;k<=n;k++) {//值域范围在这个范围且u选的方案数
if(L[u]<=tl+k&&tl+k<=R[u]) (S+=g[j][k])%=MOD;
(f[u][j+1][k]+=S)%=MOD;
}
}
if(tr<=tl+n) {
for(int j=0;j<=20;j++) nsav[u][j]=f[u][j][tr-tl];
return ;
}
for(int j=0;j<=20;j++) {//拉插
ll ans=0;
for(lim=0;lim<=n;lim++)
(ans+=f[u][j][lim]*P[lim]%MOD*Q[lim])%=MOD;
nsav[u][j]=ans;
}
}
T3 卡牌养成(card) CF1874G
水母喜欢玩一个叫做“Inscryption”的游戏,这个游戏在一个有向无环图上进行,图中有 \(n\) 个顶点和 \(m\) 条边。所有的边 \(a \to b\) 都满足 \(a < b\)。
你需要沿着有向边从顶点 \(1\) 移动到顶点 \(n\),然后与最终 Boss 战斗。
在这个过程中,你会收集卡牌和道具。
每张卡牌有两个属性:生命值(HP)和伤害(damage)。如果一张卡牌的生命值为 \(a\),伤害为 \(b\),那么这张卡牌的能量为 \(a \times b\)。
每个道具只有一个属性:能量值(power)。
除了顶点 \(1\) 和顶点 \(n\),有一些顶点会触发特殊事件。特殊事件包括:
- 你会获得一张生命值为 \(a\),伤害为 \(b\) 的卡牌。
- 如果你至少有一张卡牌,选择你的一张卡牌并使其生命值增加 \(x\)。
- 如果你至少有一张卡牌,选择你的一张卡牌并使其伤害增加 \(y\)。
- 你会获得一个能量值为 \(w\) 的道具。
当你到达顶点 \(n\) 时,你可以选择至多一张你的卡牌,并将其伤害乘以 \(10^9\)。
最终 Boss 非常强大,因此你希望最大化你所有卡牌和道具的能量之和。请你求出如果你最优地进行游戏,所有卡牌和道具的能量之和的最大值。
保证每条边 \((u,v)\) 最多出现一次。
保证顶点 \(1\) 和顶点 \(n\) 没有特殊事件。
保证对于所有 \(i\),存在一条从顶点 \(1\) 到顶点 \(n\) 的路径经过顶点 \(i\)。
我们来把讲课内容背一遍。
\(n \le 200,n-1\le m \le 2000\)
我说这题放cf是真难到恐怖吧。
我好像把题解贺了一遍写得还不如题解好。
先观察一下,你发现 \(\sum a_ib_i+\sum w\) 一定不到1e9。那么这个题就是在最大化最大的卡牌的值的前提下,最大化 \(\sum a_ib_i+\sum w\)
然后最优化经典就是如果你钦定的最优决策点不正确的话,不影响答案。
DAG形态太多了,先考虑图是一条链的情况,方便分析策略。
考虑直接枚举最终的最大的卡牌,那这张卡牌之后出现的 2,3 操作肯定全加在这张卡上。你只需要考虑怎么在遇到这张卡之前最大化 \(\sum a_ib_i+\sum w\).
因为路径固定,那你需要决策的就是 2,3 操作加到哪张卡上,我们以2操作为例,假如你已经知道所有卡最终的 \(b\),那你肯定加到现在能加的,最终 \(b\) 最大的卡上。3操作是对称的。
考虑一下,你切换加的卡,一定是因为新加了一张卡。
我们加入一张卡时,钦定它最终是不是前缀最大值。现在记录当前在哪个点,最终a最大的卡现在的值,最终b最大的卡现在的值,注意多加一维0/1表示a,b最大的是不是同一张卡。
你发现两个值域这么大就很完啊,考虑降一下。
发现如果一张卡加入的时候,现在最大的 \(a\) 和最大的 \(b\) 均大于 \(V\),那最终最大的卡一定已经找到了。
分析一下这是为什么,如果这是同一张卡的话,那显然取这张卡更优。
事实上,我们可以发现,这一定是同一张卡,假设这是不同的卡,先遇到了卡A,后遇到卡B,卡A的 \(a\) 是前缀最大,卡B的 \(b\) 是前缀最大。那么A卡的 \(b\) 肯定最终 \(<V\),不然遇到卡B时,卡B就成为不了前缀最大 \(b\) 了。
所以 \(a,b\) 两维分别为 \(O(V),O(nV)\) (当然你要交换A,B两维再跑一遍)。
现在总复杂度是 \(O(n^2V^2)\)
考虑直接钦定 \(a\) 维最终是多少,还差多少,不记录 \(b\) 维,发现这样同样可以转移,\(a\) 只有还债,\(b\) 知道最终的 \(a\) 是多少,可以直接贡献到答案。现在两维都只有 \(O(V)\) 了,总复杂度 \(O(nV^2)\)。
诶这玩意对吗。
降状态降这么大有点害怕,但是好像还真是对的,首先 \(a\) 的切换显然是刻画出来了,当前最大 \(a\) 变了就是切换了,那 \(b\) 的切换,其实影响的就是你的 \(a\) 加到谁上了,每张牌加入之后决定欠不欠债,欠多少债,其实就是决定多少的 \(a\) 加到这张牌上了,同样也可以刻画出来。
放在 DAG 上,前面部分的转移为 \(O(mV^2)\),然后发现枚举的最大的牌到 \(n\) 的路径不唯一,但是这个也是随便做一做就行了,肯定先最大化 \(delta_a,delta_b\),然后再最大化 \(delta_w\),那你从 \(n\) 开始dp,直接记录 \(f[x][a]\) 表示到x,\(delta_a\) 最大的情况下 \(delta_b\times1e9+delta_w\) 是多少,对于每个 \(x\) ,枚举一下哪个 \(a\),算一下最大卡是多少,合并一下之前的dp值。做完了。
CF1844H
写题单没写出来这题,怎么省集又遇到了。
那就,再挣扎一下!!!
\(f(a,b,c)\) 表示长度模3余数为1/2/0的链还剩 \(a/b/c\) 条。
\(f(a,b,c)=(a+b+c)f(a,b,c-1)\)
这个递推式很优美,所以我们只需要考虑求 \(f(a,b,0)\)
设 \(g(a,b)=f(a,b,0)\)
求最开始的值是麻烦的,我们考虑倒着做,那 \(g(0,0)=1\)。剩下的就是求递推式了
\(g(a,b)=(a-1)g(a-2,b+1)+b(a+b-1)g(a-1,b-1)\)
\(g(a,b)=(b-1)g(a+1,b-2)+a(a+b-1)g(a-1,b-1)\)
现在需要的就是从 \(g(a,b)\) 到 \(g(a+2,b-1),g(a-1,b+2),g(a+1,b+1)\)

还有一点补充,我们可以发现,如果涉及到的三个点都是合法的点的话,那系数一定不为0,一定可以由两个解出另一个。
可以发现,除了转移到 \(g(a+1,b+1)\),涉及到的点一定是合法的点,而这种情况我们直接从 \(g(1,1)\) 开始跑就可以了,发现这是方便的,因为 \(g(0,0)\) 第一步一定到 \(g(1,1)\)。
确实,功力不够啊,越级做题了。
Day 7
T1 删除实体(delete)
场切了。
T2 萝卜内存(robot)
小明制作了一个绿发的机器人。
这个机器人共有 \(3n\) 字节的内存,小明需要将其分成两个部分来运行程序,他将两个部分分别称作虚拟内存和现实内存(我也不知道他为什么要这么叫)。一般情况下,这个机器人都能自动进行内存的分配,从而保证程序的运行,然而,发生了罕见的多程序并行情况:有 \(q\) 个程序要在同一时间运行,每个程序要求要么 \([a_i,b_i]\) 内的内存均为现实内存,要么 \([c_i,d_i]\) 内的内存均为虚拟内存。由于程序并行过多,内存分配程序崩溃了。
当然,如果要求只是这样的话那可太好了,可是小明设计之初为了保证系统的稳定性,强制要求虚拟内存和现实内存均不可超过 \(2n\) 字节。这下小明和内存分配程序感同身受了,他现在急需一个帮手,来帮他分配内存,从而救活他的机器人,或者告诉他你的机器人没救了。
对于 100% 的数据,\(1 \le T \le 10^5,\ 1 \le n \le 3 \times 10^4,\ 1 \le q \le 10^5,\ 1 \le \sum n \le 3 \times 10^5,\ 1 \le \sum q \le 10^6,\ 1 \le a_i \le b_i \le 3n,\ 1 \le c_i \le d_i \le 3n\)。
显然线段树优化建图。
有若干个限制形如 A选了现实内存那B也要选现实内存 A选了虚拟内存B也要选虚拟内存的限制。
发现两张图很相似,而且只要满足了一张图,那另一张图一定满足,我们只需要保留一张图。
线段树优化建图部分肯定是好做的对吧,我们现在只需要考虑暴力建图。
首先缩个点。那就是3n个点要选到 \([n,2n]\) 之间,分讨。
如果所有的强联通大小都 \(\le n\),那肯定存在一种选的方案在 \([n,2n]\) 之间。
如果有联通块大小 \(>n\),那你分讨这个联通块选还是不选,因为选了这个,他所在的颜色已经满足下界了,只需要尽可能地不选。
T3 遥远恋情(far)
这个交通不便的国家共有 \(n\) 个城市,有 \(n-1\) 条道路将它们连接起来,每条道路的长度是 \(w_i\)。小明从这 \(n\) 个城市中每个城市选择了一个人,经过短时间的观察,小明发现这 \(n\) 个人中的每个人要么单身,要么 ta 的伴侣在另一个城市。有些时候事情就是那么巧,有一些异地恋情侣恰好就是小明选择的 \(n\) 个人中的两个。
不过,由于去考察异地恋的双方分别是谁就有点打探别人的隐私了,所以小明果断打住了,转而去研究了另一个问题。对于一对异地恋的情侣,记他们的遥远度为两人所在城市之间最短路径的长度。假设小明的运气足够好,这 \(n\) 个人中恰好有 \(k\) 对情侣,那么这 \(n\) 个人的总遥远度就是这 \(k\) 对情侣的遥远度之和。
股票的事情最终结果不尽人意,给了小明很大打击,小明早就成为了悲观主义者。他想知道,在已知 \(n\) 个人中恰有 \(k\) 对情侣,但不知道分别是谁的前提下,在所有可能的情况中,遥远度的最大值是多少。
当然,小明对自己的运气到底有多好没什么信心,于是他想要对每个 \(k = 1,2,\dots,\lfloor \frac{n}{2} \rfloor\) 求出这个遥远度的最大值。
对于 100% 的数据,\(1 < n \le 10^6,\ 1 \le w \le 10^6\)。
这题Wei_Han那有非常详细的题解,说实话不想写了。不过还是随便写点吧。
性质1:任意图最大匹配点集都是增量的,这个你考虑 \(S_k\) 和 \(S_{k+1}\),考虑一下匹配的联通块形状,交换证明一下。
性质2:任意两组匹配肯定边相交
性质3:所有匹配过同一点,这个交换证明一下就行
性质4:对于一个点集,他们的重心一定在 这个点集dfn序第 \(\lfloor \frac{|sz|}{2} \rfloor + 1\) 到根的链上。
注意到两次重心移动,中间肯定一个点都没有,距离是好维护的。
分讨重心向上和向下维护。
向上是子树左边和右边的和当前重心的LCA的较深值。
向下根据性质4,跳到当前重心的较大的子树中,求子树内最左最右点的LCA。
Day 8
T1 背叛的爱丽丝(alice)
爱丽丝和格林在玩游戏。游戏规则如下:
- 爱丽丝先手。
- 初始有一个集合 \(S = \{1,2,\dots,n\}\),以及一个空序列 \(P\);
- 双方轮流从 \(S\) 中选择一个数 \(x\),将 \(x\) 加入序列 \(P\) 的末尾,并从 \(S\) 中删除 \(x\);
此外,还有一个给定的正整数 \(k\) 用于判定胜负。具体而言,本题有两套判定胜负的规则:
- 规则 1:第一次使得 \(P\) 的最长上升子序列长度变成 \(k\) 的选手获胜,或者当对手无法操作时(也就是 \(S\) 被删空了)也获胜。
- 规则 2:第一次使得 \(P\) 的最长上升子序列长度变成 \(k\) 的选手失败,或者当自己无法操作时(也就是 \(S\) 被删空了)也失败。
现在,游戏已经进行了 \(q\) 轮,保证 \(q\) 为偶数,也就是爱丽丝和格林都已经分别操作了 \(\frac{q}{2}\) 次,依次给出这 \(q\) 次操作中他们选择的数 \(a_1,a_2,\dots,a_q\),保证这时还没有分出胜负。
由于 \(q\) 是偶数,所以接下来仍然是爱丽丝先手。假设接下来的游戏过程中,爱丽丝和格林都绝顶聪明,你需要判定爱丽丝是否必胜。若爱丽丝必胜,请你再求出爱丽丝在接下来的第一步(也就是整个游戏的第 \(q+1\) 步)有多少种操作方案,可以最终获胜。
对于全部测试数据:
- \(1 \le T \le 1000\)
- \(3 \le n \le 10^5\)
- \(v \in \{1, 2\}\)
- \(2 \le k \le 10^5\)
- \(2 \le q < n\),且 \(q\) 为偶数
- \(\sum n,\ \sum q,\ \sum k \le 10^6\)
博弈好难啊好难啊好难啊。
规则1场切了。
抽空加训博弈。
T2 线性代数入门指南(linalg)
有 \(n\) 个 \(3 \times 3\) 的矩阵 \(A_1, A_2, \dots, A_n\)。设 \(S_n\) 是全部 \(n\) 阶排列的集合,求出下式的值对 \(998244353\) 取模的结果:
对于全部测试数据,保证 \(1 \le n \le 40\),矩阵元素为 \([0, 998244353)\) 内的整数。
BEST定理
考场上在想三层图,3*n个点,然后跑个类哈密顿环,然后发现可能不联通,感觉不是很好修,爆炸了。
实际上是3个点的图求欧拉回路,其实也挺有道理的,3个点的图肯定比n个点的好考虑也更好check。
BEST定理,然后注意要判断一下图存不存在欧拉回路。BEST定理可能可以看我博客,不过感觉有点过于感性和胡扯了。
额啊我还是多写两句吧。
从前往后扫1到n,考虑每个位置选了哪条边(u,v都在1到3里取,重边条数就是权值,你要选一条加进图里)根据BEST定理,首先你要求根为1的内向生成树,但是三个点,你可以直接压状态,现在三条边哪些边被选了,反正形态不是很多。为了算答案,要记录每个点的出度,同时注意BEST定理的使用条件要求他本来就是一个存在欧拉回路的图,要保证入度=出度,把每个点的入度和出度计入状态里,但是注意到三个点的入度之和和出度之和是确定的,你可以只记录两个点的入度和出度具体是多少。
T3 失忆(amnesia)
格林有一棵 \(n\) 个点的树 \(T\),点的编号为 \(1\) 到 \(n\) 之间的正整数。他会对这棵树做如下操作:
- 第一步,从 \(T\) 中选出一个点 \(A\),接着把和 \(A\) 点相连的边都抹去,之后打乱点的编号。假设得到的森林的形态是 \(T_1\)。
- 第二步,从 \(T\) 中选出一个与 \(A\) 不同的点 \(B\),接着把和 \(B\) 点相连的边都抹去,之后打乱点的编号。假设得到的森林的形态是 \(T_2\)。
- 注意,这两步是独立的,即每一步都是在原先的树 \(T\) 上进行的。
现在,格林忘记了原来的树是什么样子,但是他记得 \(T_1\) 和 \(T_2\) 的边集。请你帮他还原出原来的树。任意一棵满足条件的树都可以。
对于全部测试数据,有 \(2 \le n \le 2000\),\(1 \le a,b \le n\),\(a \neq b\)。保证给出的边集合法,且存在至少一组解。
先放个xor shift 不过注意不能生成0
unsigned xorshift32(unsigned x) {
x ^= x << 13;
x ^= x >> 17;
x ^= x << 5;
return x;
}
为了防止被卡可以先异或一个随机数。

对于图A,图B,枚举另一个图中删掉的点在当前图是哪个点,然后删掉这个点,给他周围的标上0/1,表示和枚举的点联通还是不联通。
然后我们发现实际要做的事情就是0和1匹配,最多只有一个1和1匹配。
理论上就做完了,但是非常恶心他还要构造方案,我先来口胡一下。
我们设图1删掉的点为X,图2删掉的点为Y
我们先把所有的联通块匹配对拉出来,以图1的点的编号为基础,先把图1的所有的边连起来,现在要考虑每个联通块哪个点和X连了。那你对图2中所有和1连的点的哈希值求出来,对于每个匹配,在图1中的联通块中的点找对应哈希值。
写完了,这玩意确实是对的,但是我写的时候没带脑子倒是。
Day9
T1 如何彻底消失(disappear)P12936
给定度数序列,构造一棵度数为给定度数序列的仙人掌 \(n \le 2000\)
考场上考虑得不够就开始写了,不过感觉确实水平不够,还得加油。
但是不管怎么样我考场上怎么写那么麻烦???
首先先考虑全是偶度点怎么构造,首先先画个大环出来,然后从中间捏成两个环,那捏的位置的点度数就增加了2.
好吧正经点说,先挑出来一个度数最大的点作为基础,然后再挑剩余的点的度数最大的两个点,和这个点连成三元环。维护每个点还能接多少个点,每次重复这个过程接度数最大的两个点。如果最后有剩余的度数为2的点,随便找条边把这个点插进去。
事实上,这个构造确实也能构造到全局上界。我们考虑每次挑最大的点接后面的,那肯定能够尽量保证结构数量最大
(或者说我们先把每个点的度数-2,表示第一次,然后剩下的就是他要连多少个儿子节点,这时候能看成一棵树形,如下图,蓝线是所说的树形)

然后考虑奇度数点,注意到(猜到)一个奇度数点必和一条不在环上的边相邻。这是显然的,如果一个奇度数点周围的所有的边都在环上的话,那每条边必须与另一条边匹配,每个匹配度数+2.那相当于,每两个奇度数点,必定要浪费一条边,让这条边不在环上。
那一个简单的构造是,每次匹配两个奇度数点(显然奇度数点一定是偶数),让这两个点相连,在之后的过程中,把这两个点当一个点考虑。做完全部的过程,再展开,注意要保证每个环最终只和一个点相邻,这个只需要展开的时候判断一下应该就可以了。
但是这个还是有一种情况处理不了,如果两个奇度数点度数都为1,连起来就炸了,没办法和任何其他点联通了。
那这也没办法了,首先我们先尽量把度数为1的点和其他奇度数点匹配。如果还剩下1的话,那只能一个点浪费一条边,每次选两个1度点和一个偶度数点匹配。
这看起来就是最优的了吧,不太想证了。
T2 如何变得善良(kind)qoj7584
给三维空间的 \(n\) 个球,求球两两之间第 \(k\) 小距离。 \(n \le 2e5,k \le 300\)
写了第一遍题解写假了。
二分一下距离 \(mid\),把所有球的 \(r\) 都加上 \(\frac{mid}{2}\)。
嗯我觉得也就这步看起来就很有道理。
我来把题解背一遍,首先先按照半径从大到小扫 \(r\),在空间里画出长度为 \(2r\) 的方块,这样每个球只会只会和这个块和相邻的块的球相交。那每个球和相邻的块暴力判断。扫到半径 \(<\frac{r}{2}\),就重构所有的块。
然后如果一个块内的球数超过一个 \(O(\sqrt k)\) 的阈值,那必有 \(k\) 对相交(但说实话的我算了一下,这个常数还是相当大的???)。找到第一次大于 \(k\) 的值 \(ans\),再对 \(ans-1\) 跑一遍求出方案,剩下的答案都是 \(ans\).
我们再细说一下第一部分,每段把这一段大小[L,R]的都加入哈希表,扫[1,R]的球,检查周围的联通块。
官方题解说的每个点访问到的点的个数只会有 \(O(\sqrt k)\),但是这真对吗。毕竟每个点要扫 \(\log\) 层。不过我们至少可以分析到 \(O(\sqrt {k \log n})\) 这是因为 \(\sum_i^{\log n} k_i^2 \le n\),求得 \(\sum k \le n \log n\)
不过看起来是不是代码都是写的直接多1只log的??反正能过不管了。
T3 如何赚到大钱(millions)P12821
你转生到了异世界,成为了一名勇者。为了伸张正义,你将和一条巨龙结伴,一同打倒邪恶的农民。
异世界中总共有 \(n\) 组农民,第 \(i\) 组有 \(a_i\) 个小兵。巨龙和农民的战斗按照如下方式展开。
最初,巨龙有 \(h_d\) 的血量,每个敌方小兵都有 \(h_p\) 血量。也就是说,第 \(i\) 组小兵在开始时总共有 \(H_i = h_p \cdot a_i\) 的血量。
战争由几轮战斗组成。在每一轮中,都会发生两件事:
- 首先,巨龙选择一组小兵并攻击它们。该组农民的总血量会下降 \(d\)。如果这组农民的总血量为 0,则这组农民覆灭了。
- 然后,每组小兵攻击巨龙。一个具有总血量 \(H\) 的农民组中,有 \(\left\lceil \frac{H}{h_p} \right\rceil\) 个小兵还活着,每个活着的小兵都会给巨龙造成一单位伤害。
如果巨龙的生命值在任何时候为零或更低,它就会死亡,你也就输了。如果所有小兵都被摧毁了,那么你就赢了。
你需要确定尽可能小的 \(h_d\),使得存在一种策略赢得战斗。
- 对于单组测试数据,\(1 \le n \le 1000\),\(1 \le d, h_p, a_i \le 10^9\),\(h_p \cdot \sum a_i \le 10^9\)。
- \(\sum n < 1000\)。
我说你们不等式功底怎么都这么好啊,欺负我一个没学明白不等式的是吧。虽然我知道这是板子。。。
首先有一个直接贪的做法,由01 on tree的经典贪心套路,相当于一棵根接若干条链,然后每次取最小的和父亲合并。当然这玩意T了。
为了优化这个东西,我们考虑先把链内部合并了,然后最后在根节点把所有合并之后的链归并起来。
因为总血量 \(\le 10^9\),所以这题不拿 SB Tree 还有的做。
设 \(H_i=h_p \times a_i,H=h_p \sum a_i\)
由题意知 \(H \le 10^9\)
最麻烦的就在于这个上取整了对吧,我们一个周期一个周期考虑(砍死的小兵数量是周期性的)
周期长度最多为 \(h_p\),并且一个周期最多 \(a_i\) 个有值的位置,所以一个周期最多只有 \(\sqrt H_i\) 个有值的位置。然后我们有若干个周期,那我们快速幂一下,我们需要保证快速幂过程中,最终合并出来的块数不会太多。我们现在来证明整个快速幂过程中,块数都是 \(O(\sqrt H_i)+O(1)\) 的

(感觉画的图应该色盲色弱友好吧)
上面画的两个链拼起来的情况,每个链有四个块,把每个链分为>平均值和<平均值两个部分(等于可以得出结论之后讨论一下,反正好考虑的,略了),第一条链>平均值部分不变,第二条链<平均值部分不变,发现最终合并结果一定是吧第一部分<平均值部分和第二部分>平均值部分合并成一个块。所以最多加 \(O(1)\) 段(是不是只有1段,我不知道)
那你快速幂之后每个链也只有 \(O(\sqrt H_i)\) 对吧,那所有的链长度之和只有 \(\sqrt {nH}\) (注意这里 \(H=\sum H_i\),那最优情况肯定是平均分配了,你可以拿柯西不等式证一下,我是直接问的gemini)
那分治把所有的链归并起来,总复杂度 \(O(\sqrt{nH}\log n)\)
加训加训加训

浙公网安备 33010602011771号