2022.2 好题
UER#9 - 赶路
https://uoj.ac/contest/61/problem/604
考虑分治,我们设 \(f(u,v,S)\) 为从 \(u\),经过点集 \(S\),到达 \(v\) 的过程( \(S\) 不包括 \(u,v\) )。
那么我们从 \(S\) 中随机选一个点 \(x\),然后从 \(u\) 经过点集 \(S_0\) 到达 \(x\),然后从 \(x\) 经过 \(S_1\) 到达 \(v\)。也就是 \(f(u,x,S_0),f(x,v,S_1)\)。
怎么求得 \(S_0,S_1\)?我们将 \(u\) 和 \(x\) 连线为直线 \(l\)。在直线上方的为 \(S_0\),在直线下方的为 \(S_1\)。当然,最后 \(S_1\) 和 \(v\) 应该在 \(l\) 的同侧,如果在异侧,就交换两个集合。
递归边界: \(S\) 为空集时,走到点 \(u\)。
UER#9 - 知识网络
https://uoj.ac/contest/61/problem/605
做法一:
对于每个标签建立一个虚点,每个点向对应标签连边权为 0 的边,标签向对应点连边权为 1 的边。然后就可以 bfs 求最短路了,这样是 \(O(nm)\) 的。
做法二:
建立虚点后,枚举标签。设现在枚举到第 \(i\) 个标签,所有 \(i\) 号标签的点(简称初始点)一起跑最短路(多源多汇),得到每个点的 \(dis\) 值。进而可以建立出最短路 DAG(类似最短路树,但是因为多源,所以是 DAG)。
思考一下,对于一个点 \(u\),初始点怎么到达它?要不然是不走 \(i\) 号虚点,通过原本的道路或者其它标签的虚点走到 \(u\),这种点我们称为孤勇者。还有一种办法就是走到虚点,然后走到孤勇者点,然后走孤勇者点相同的路径,这种点称为小弟。
发现,走到 \(u\) 点的最短路 \(dis_u\),必然是由孤勇者点开始的,而从小弟点开始走,最短路必定是 \(dis_u+1\)(因为花费一步就可以到孤勇者点,然后和孤勇者点一模一样)。
如果有 \(x\) 个初始点,其中有 \(x_0\) 个孤勇者点,那么 \(u\) 会产生 \(x_0\) 对长度为 \(dis_u\) 的路径;会产生 \(x-x_0\) 对长度为 \(dis_u+1\) 的路径。(代码实现时要加一,因为题面中路径长度的定义为路径点数而非边数)
而且,在最短路 DAG 上,\(u\) 对应的小弟点是走不到 \(u\) 的(由最短路 DAG 的定义)。所以只用统计一下最短路 DAG 中,每个点有多少个初始点为前驱就好了(前驱指可以到达一个点的点,无论直接还是间接连边),前驱一定是孤勇者点。但是可惜的是,维护前驱,这是个 NP 问题(好像是。),唯一的办法就是暴力维护每个点的前驱集合,然后暴力转移。空间复杂度 \(O(n^2)\),时间复杂度 \(O(km\times n)\) (转移一次集合就要 \(O(n)\),要枚举每条边转移)。
做法三:
在做法二的基础上,我们每次只维护 \(w=60\) 个点的集合(也就是分批运行集合),然后只用一个 long long
保存一个集合,这样转移集合就是 \(O(1)\) 的了(S[v]|=S[o]
)。空间复杂度是 \(O(\frac{n^2}w)\),时间复杂度 \(O(km+\frac{n^2}{w})\)。可以通过本题。
UER#9 - 面试
https://uoj.ac/contest/61/problem/606
看起来好烦啊,不想做。
UER#8 - 打雪仗
https://uoj.ac/contest/47/problem/454
sol 1
发现这个通信题非常前卫,并不只是一个人通信给另一个人,另一个人报答案,而是两个人可以随意地互相发送信息!
于是当甲报出 \(i\) 位置的数字时,乙发送 \(0/1\) 代表下一个位置的数字是 \(i+1\) 还是 \(i+2\)。(如果都没有就报 1)。
如果随机数据,打表得,这个的期望的传递次数是 \(\frac 4 3 n\) 的。但是遇到 000000111111
这种数据,就被卡成 \(\frac 3 2 n\) 了。
于是约定一个随机种子,将数据打乱一下就可以期望 \(\frac 4 3 n\) 了。
sol 2(有锅)
把 01 串大约地切割成,三个差不多一样长的串(也就是,长度约是 \(\frac 23n\))。那么,必有一个串,有乙的元素的数量,不少于一半。
乙把这个串的序号告诉甲,甲直接把整个这个串告诉乙。
还有两个串呢?用 Sol 1 的方法就好了。(应该是…吧?)
UER#8 - 雪灾与外卖
https://uoj.ac/contest/47/problem/455
【反悔贪心】(也可以说是【模拟费用流】)
因为每个人都要去店,所以我们先在 -inf 处放置 \(n\) 个店。
我们从左到右枚举每一个元素,如果是一个人,那么就在“店堆”中找到最小的代价(即使是正数,因为每个人都一定要去店),更新答案,然后将人插入人堆中。(注意:如果最小的代价,对应的店,容量大于一,那么就将店的容量 \(-1\) 然后再插回店堆中)。
如果是一个店,同样地,就循环地在“人堆”中找到最小的代价,直到最小的代价是正数,或者店的容量被消耗光。同样地,拿到最小代价后,更新答案,将店插入店堆(注意:……同上)。但是店有两个增加的操作:
- 如果这个店还有容量,那么将剩余的容量对应权值塞进店堆里;
- 如果这个店花费了一些流量,那么将这些对应的权值塞进人堆里。如果后来有一个店 \(B\) 匹配了这个权值,代表 \(B\) 夺取了原来店的那些人。
可能有疑问:为什么人不会有增加的操作? 简洁地说,因为人是不带权(\(w_i\))的,只和距离有关。
如果有两家店 \(u,v\),有两个人 \(a,b\),满足 \(u<a<v<b\),那么最优解会是 \(u-a,v-b\),而非 \(u-b,v-a\),因为这白白多走了一段路。
所以就不会有下面的情况:
\(a\) 匹配了,在他左边的,有一个只有一个菜的店 \(u\)。\(a\) 的右边有一个 \(b\),结果枚举到 \(b\) 的时候,让 \(b\) 去匹配 \(u\),而让 \(a\) 去匹配另外一个其它的位置。
同时,我们也可以根据这个,说明时间复杂度:
不会证时间复杂度,但是操作是线性的。加上优先队列,是 \(O(n\log n)\)。
UER#8 - 许愿树和圣诞树
https://uoj.ac/contest/47/problem/456
类比 HNOI2017 单旋:
用 LCT 维护这个树。
由于只用查询最大值和最小值,由于 Spaly 的性质,所以最大值必须在整个树的最右下角,最小值必须在整个树的最左下角。
假如现在的点是 \(u\),父亲是 \(fa\),儿子是 \(v\)(因为是最值,所以只会有一个儿子),树根是 \(root\),那么执行:
cut(u,v),cut(u,fa),link(u,root),link(v,fa)
即可。至于为什么,画个图就好了。
但是回到这题,并不是查询最值,所以我们 aces(u,root)
,得到一个链。设链上的点,左子树有 \(u\) 的为 0 点,右子树有 \(u\) 的为 1 点。那么链可以表示成一个 01 串。依次地像上面的思路一样,处理每一个极长的 0 串或 1 串。
这个可以证明是均摊 \(O(\log n)\),但是要用到势能分析。
对于操作 2 和操作 3,就是在 Splay(注意是真正的,在 LCT 上的 Splay 而非 Spaly)上递归就好了,\(O(\log n)\)。
总时间复杂度为 \(O(Tn\log n)\),但是实现显然又难又性价比低。
UER#7 - 短路
https://uoj.ac/contest/35/problem/244
显然地,只能往下或者往右走,是最优的。(想一想,为什么?)
然后我们可以沿着 \(y=x\) 切开,那么左上角怎么走,右下角就会对称地走。
枚举我们会在哪里闯过楚河汉界。设为第 \(i\) 层。
首先,每一层我们都会刚好纵向走一次,至少横向走一次。
纵向的值是固定的,先不考虑。
横向的,如果第 \(j\) 层是 \(a_1\sim a_j\) 的最小值,那么能走就走。否则不做停留(也就是不在这一层横向走)。
这个结论有点难想,但是想到了后,就是存粹的贪心了。
UER#7 - 天路
没怎么做过的误差题目!
注意到,如果 \(ans_i\in [1.05^x,1.05^{x+1}]\),那么输出 \([1.05^x,1.05^{x+1}]\) 中的任何一个整数都是合法的。
注意到, \(ans_i\) 是单调递增的。
所以枚举每一个区间 \([1.05^x,1.05^{x+1}]\),统计有哪些 \(ans_i\) 在这些区间就好了。
怎么统计?找到满足 \(\max-\min\) 在 \([1.05^x,1.05^{x+1}]\) 中最大的区间(用尺取法维护)即可。ST 表。
UER#7 - 套路
https://uoj.ac/contest/35/problem/246
根号分治。
对于 \(len\le \sqrt m\) 的,直接用 \(s(l,r)=\min(\ s(l+1,r),s(l,r-1),abs(a_l-a_r)\ )\)。
对于 \(len>\sqrt m\) 的,\(s\) 只会有 \(\frac m {len}=\sqrt m\) 种取值,为 \([1,\sqrt m]\)。(如果是类似 1 n 1 n 1 n
的数据,会被算入第一种情况)。于是枚举每一种取值,尺取法维护即可。
总时间 \(O(n\sqrt m)\)。
套路:对于这种用到值域,用到区间本身长度的用根号分治。
UER#6 - 票数统计
https://uoj.ac/contest/29/problem/209
显然如果 \(x>y\) 那么就是前缀的条件;如果 \(x<y\) 就是后缀的条件。
对于条件【前 \(x_1\) 个人有 \(y_1\) 个通过】和【前 \(x_2\) 个人有 \(y_2\) 个通过】,可以转化为【 \([1,x_1]\) 有 \(y_1\) 人通过】和【\([x_1+x_2]\) 有 \(y_2-y_1\) 人通过】。
所以可以将条件分为若干个独立的区间,将区间的贡献相乘即可。
但是还有一种东西就是 \(x=y\)。
发现只用找到最大的 \(x=y\) 的 \(x\) 就好了,因为如果这个满足了,其他也一定会满足。
枚举 \(x=y\) 是前缀还是后缀,最后容斥一下减去【前缀和后缀都满足 \(x=y\)】 的方案数就好。
UER#6 - 寻找罪犯
https://uoj.ac/contest/29/problem/210
你发现这是个“是否”问题,于是 2-SAT。
设立一下条件中的元素: 代表【证词为真】/【证词为假】/【人是好人】/【人是犯人】的四种点,按照语文阅读理解推一下就好了。
比较重要的是【证词为假】,此时这个条件要和 \(x\) 说的其它证词的【证词为真】连边。
就相当于有 \(n\) 个点 \(a_i\) 和 \(n\) 个点 \(b_i\),对于每个 \(i\),\(a_i\) 要和 \(\forall j\ne i\ b_j\) 连边。前后缀优化即可,太显然了!!真是大水题。
UER#6 - 逃跑
https://uoj.ac/contest/29/problem/211
学长讲过但还是不会,明天问问人。
UR#19 - 清扫银河
https://uoj.ac/contest/51/problem/513
这两个操作都看起来很蠢,试图将他们简化:
-
对于操作一:
- 如果只给一个点染色,那么就是使得连着的边翻转。
- 如果给一条边的两个点 \(x,y\) 染色,那么就相当于只给 \(x\) 染色并作操作一,只给 \(y\) 染色并作操作一。
- 如果给几个毫不相干的点染色,那么就相当于分别地,只给一个点染色并作操作一。
于是发现,我们可以把 1 操作转化为,每次只给一个点染色,使得其连着的边翻转。如果转化为这个模型,有一个结论是,每个点至多染色一次是最优的。(可能会有疑问,就是如果不转化为这个模型,会不会使得答案更优?事实上,待会会说明,转化为这个模型后,虽然可能不是最优,但必可以使得答案小于 \(m+1\))
-
对于操作二:
我们建出图的一个生成树。那么对于一个非树边 \(p-q\),\(p-lca(p,q)-q\) 形成了一个简单环。那么对于原图上的任意一个环,都可以由若干个简单环 异或得到(这里异或是直接对边异或,即如果一个边在偶数个简单环里,就不计算这个边)。
所以 2 操作转化为,每次选择一条非树边,将对应的简单环边权翻转。同样,每个非树边至多操作一次是最优的。
发现,操作一至多有 \(n\) 次,操作二至多有 \(m-n+1\) 次,所以总操作数刚好不超过 \(m+1\)。
可以直接暴力地高斯异或消元(\(a_i\) 代表是否执行 \(i\) 操作,每个方程代表对 \(u\) 的影响的操作有哪些),时间 \(O(\frac {Tm^3}w)\) 可以 70 pts.
100pts 的解法看不懂。
UER#5 - 万圣节的南瓜灯
如果好点组成的图没有环,那么对于任意一个四个点的正方形 \((i,j),(i+1,j),(i,j+1),(i+1,j+1)\) 都必须要一个坏点。
所以答案为 Yes
的必要条件为 \(nm\le 4K\)。特判后,暴力做即可!
UER#5 - 万圣节的数列
求助,怎么样暴力可以拿 20 pts 😭
猜测一个性质:不会有长度大于二的等差子序列。
分治。
首先将奇数放在左边,偶数放在右边,这样就不会有跨中间的,长度大于二的等差子序列了。
然后对于左边一段分治:全部都除以二,再接着,奇数放在左边,偶数放在右边。这样左边都是 % 4 余 1 和模 4 余 3 的了。这样就不会有跨中间的,长度大于二的等差子序列了。
一直这样分治下去即可。
但是对于同样的数字怎么办?那么就设定一个阈值 \(D\),如果递归超过 \(D\) 层,还是不能区分当前的元素,那么就不再操作即可。因为 \(a\le 10^9\) 所以 \(D\) 取 \(30\) 即可。
UER#5 - 万圣节的糖果
好奇怪的题啊,完全想不到……
首先假设集合是无序的,最后乘上 \(m!\) 即可变成有序的!
50 pts
设 \(f(i,j,k)\) 为放置了前 \(i\) 个糖果,有 \(j\) 组集合的末尾元素与 \(i\) 奇偶性相同,有 \(k\) 组集合的末尾元素与 \(i\) 奇偶性相异,的方案数。
100pts
设置一些非常奇怪(而且难以想到)的东西。
假如题意改成【需要让每一组集合都奇偶性相同】,那么设 \(h(i,j,k)\) 与 \(f\) 的定义一样,dp 即可。
如何 dp?首先我们设 \(g(i,j)\) 是将 \(i\) 个糖果放到 \(j\) 组集合的方案数。
那么,由于 \(1\sim i\) 种刚好有 \(\lceil\frac i 2\rceil\) 个与 \(i\) 奇偶性相同的数字,\(\lfloor\frac i 2\rfloor\) 个相异的数字,所以有:
发现事实上 \(h\) 是个伪 dp。。。不过,这是 \(O(n^2)\) 的。
然后发现 \(f(i,j,k)=h(i+1,k+1,j)\)。于是就做完了。
证明
归纳法,具体看题解。
反正我觉得这种 dp 没有任何启发意义。
如果会容斥做法的找我
UER#4 - 被删除的黑白树
https://uoj.ac/contest/20/problem/139
首先设最浅的叶子 的 深度是 \(len\),那么答案的上界肯定是:每个叶子到根的深度都是 \(len\)。
根据构造题套路,证明这个答案的上界一定可以取到。
我们按照深度,从小到大,枚举每一个叶子节点,看它到根有 \(x\) 个黑点,那么就再从叶子节点往上染黑 \(len-x\) 个白点。根据直觉和感性画图,这是对的。
UER#4 - 被粉碎的数字
https://uoj.ac/contest/20/problem/140
显然是数位 dp。
发现记录数位和是不行的,因为不能递推。所以记录 \(f(x),f(kx)\) 的值然后递推即可。
但是我们发现 \(f(kx)\) 的值很难去计算。
于是我们反过来,从低位到高位数位 dp。具体方法是:记录 \(typ\) 代表现在 \(1\sim i\) 表示的数字 与 \(n\) 的 \(1\sim i\) 表示的数字大小如何。如果第 \(i\) 位不同,则直接更新,如果相同就是 \(typ_i=typ_{i-1}\)。
为什么要这样?我们要记录一下最高位的数字是多少,以便转移。
比如我从 56 X 7 转移到 456 X 7:
56
x 7
-----
42
35
-----
392
余数就是 3,这样我们加入 4 这个高位的时候,就可以直接:
4....
x 7
------
3...
28
------
31...
注意:以下 dp 式子并非正确的,\(x \bmod 1000\) 事实上需要把 3 位都加起来!
那么记录数位 \(i\),\(f(x)\) 的值 \(a\),\(f(kx)\) 的值 \(b\),当前的余数是什么 \(j\),以及比较状态 \(typ\)。
但是发现 MLE 了……
发现我们最后只需要 \(a=b\) 而不关心 \(a,b\) 的值。所以我们可以改为记录 \(c=a-b\)。
这样就过了。
(事实上要记录一下最高第一位,最高第二位,最高第三位?)
UER#4 量子态的棋盘
https://uoj.ac/contest/20/problem/141
开始讨论赛了,有空在做!
杂题选讲
https://www.cnblogs.com/lgj-lgj/p/15868928.html
CF1383F - Special Edges
https://www.luogu.com.cn/problem/CF1383F
枚举每一条特殊边是否为最小割。设 \(f_{S}\) 为,每条边割或不割的状态是 \(S\),其余 最小割的边 的最小值,则 \(ans=min(f_S+\sum\limits_{S_i=1}w_i)\),\(w_i\) 就是每次输入的。
但是还是要做 \(2^k\) 次网络流来求出 \(f\),TLE!然后我们从 \(S\) 转移到 \(S|(1<<i)\),只用在残量网络上加边即可。 怎么记录?暴力存边。\(e_{S,i}\) 状态 \(S\) 的第 \(i\) 条边。\(S\gets S\ xor\ lowbit(S)\)。
要用 FF 求,就是不 dfs 了,直接在 bfs 上面找到路径,直接搞。因为边权小所以对的。
CF1416F - Showing Off
https://www.luogu.com.cn/problem/CF1416F
因为格子不能向边界外面连边,所以最后是内向环套树森林(不会证明。)。
然后我们可以让所有环长度都是 2,这样更加方便:
比如:
D L
R W
可以变成:
D L
W L
会不会改环长前可以构造方案,改后就不行了?不会的,因为是内向树森林,把对应的 \(A\) 调大一点就好了。
那么就相当于骨牌覆盖。
但是:大的只能向小的连边。
为什么?因为如果小的向大的连边,但是大的不向小的连边,那么小的权值为 \(A_1+A_2\),大的权值为 \(A_2\)。这是矛盾的。
一个环的话,两个权值都是 \(A_1+A_2\)。
所以有一个没有用的推论:如果有一个点,它的四面都大于它,则直接无解!
所以如果有一个点,它的四面都大于等于它,那么它就一定在环上。称为好点。
所以仍然是骨牌覆盖(一个骨牌,代表这两个点成环):黑白染色,二分图。然后可以跑费用流或者上下界:
连边:\(a\) 向 \(b\) 连边,当且仅当 \(val_a\ge val_b\)。
费用流:给好点的出边,费用都是 1。最大费用最大流。如果最后费用不是好点数量,就是无解。\(O((nm)^2)\)!? 但是能过,玄学。
对于图 \((V,E)\),费用流是 \(O(VEf)\) 的,其中 \(f\) 是最大流。所以说费用流没有准多项式复杂度。但是一般看成 \(O(VE)\)。
上下界:好点 \([1,+\inf]\),其他点 \([0,+\inf]\)。\(O(nm\sqrt {nm})\)。
输出方案:看网络流图中每个点向哪个点连边。然后拓扑排序一下就好了,毕竟这个环套树的环长度只有 2。
UPD:本来想用费用流水的,但是 zz 讲课太好了,良心发现,决定写上下界!
CF737E - Tanya is 5!
https://www.luogu.com.cn/problem/CF737E
CF1284G - Seollal
https://www.luogu.com.cn/problem/CF1284G
ZZ 写题解,真是天仙下凡!
首先给 \((1,1)\) 的左边与上边放上两个白点:\((0,1),(1,0)\)。于是不用考虑 \((1,1)\) 了。
每个黑点连接相邻的白点,然后最大匹配。然后将最大匹配的一对点缩点,再连边即可。(应该是)
\(O(nm\sqrt {nm})\)
CF1552G - A Serious Referee
https://www.luogu.com.cn/problem/CF1552G
不会证明,但好像很对:YES 当且仅当所有的 01 序列可以被复原。
于是就暴力一点,啊。我们暴力维护当前可达的状态,然后暴力按照操作升序排列。如果初始的所有状态,最后弄到的状态全都是 00001111 那就是 YES 了。
怎么维护?我们设当前进行到了第 \(i\) 操作。序列状态是 \(S\),要操作的位置 集合 是 \(T_i\),那么我们只需要关注在 \(T_i\),但不在 \(T_{i-1},T_{i-2}...T_1\) 的位置,枚举这些位置里有多少个 0 就好了(也不用找顺序,因为排序完肯定 0 在前边)。
时间复杂度懒得想,好像是 \(O(\ (\frac{n+k}k)^k\ )\)。
CF1599B - Restaurant Game
https://www.luogu.com.cn/problem/CF1599B
讲过但仍不会!好像是大分类讨论!
CF1580E - Railway Construction
https://www.luogu.com.cn/problem/CF1580E
同上。
CF1552F - Telepanting
https://www.luogu.com.cn/problem/CF1552F
走到 \(i\) 时,所有入口在 \(i\) 之前的,都肯定是开启状态。
设 \(f_i\) 为从如果走到 \(x_i\) 并且被传送了, \(y_i\) 走到 \(x_i\) 要多少时间。
由第一句话得,\(\Large f_i=x_i-y_i+\sum\limits_{y_k\in[x_i,y_i]} f_k\)。
\(ans=x_n+1+\sum f\)。
CF1583G - Omkar and Time Travel
https://www.luogu.com.cn/problem/CF1583G
和上一题差不多,但是更难了。
设 \(f_i\) 就是从 \(y_i\) 走到 \(x_i\) 要多少次数。那么 \(\Large f_i=1+\sum\limits_{[x_k,y_k]\in [x_i,y_i]} f_k\)。树状数组。
但是怎么求答案呢?我们考虑要走哪些传送门。对于一个钦定要走的传送门 \(x_0,y_0\),那么肯定也要走 \(x_i<x_0,y_i<y_0\) 的(\(x_i>x_0\) 的已经被统计进 \(f_i\) 了,现在统计的是相互独立的元素)。那么就找到所有要选的,把 \(f\) 加起来就好了。也是用树状数组找到哪些要选。
注意,求答案的时候指的是 要走过哪些传送门才能达到最终目标,而预处理是 走一个传送门要花费多少时间。
CF1305H
https://yhx-12243.github.io/OI-transit/records/cf1305H.html
Part 1
我们想要知道得分 \(s_1,s_2...s_n\) 是否符合条件。
弄出上下界的理论模型(略,看上边题解)。
将 \(l_i,r_i,s_i\) 从大向小排序(不需要捆绑着排序,因为网络流的边是无序的)。经过(他人的)推导,我们可以得到:
符合条件的充要条件:
暴力做是 \(O(nm)\) 的。
从小到大枚举 \(x\),则我们可以求出右边的结果(因为与 \(y\) 无关)。然后左边就是 \((y,\sum\limits_{j=y+1}^m s_j)\cdot (x,1)\) 向量乘积,求这个东西的最大值。
然后你发现,\(\sum s_j\) 这个东西是随着 \(y\) 增加而单调递减的,但是差分数组是单调递增的(\(s_i\) 大向小排序了)。
然后他就是一个下凸包。从左上到右下,弧倾向于左下角 的下凸包。
我们得到了下面的东西:
一个下凸包,和一个 \((x,1)\) 点。我们需要在下凸包上找到一个点,使得它与 \((x,1)\) 的向量点积最大。
“引理” :
过 \((0,0),(x,1)\) 做直线,斜率显然为 \(\frac{1}{x}\),然后做一条垂线(也就是斜率 \(-x\)),使得垂线与下凸包相切。垂线与下凸包的切点就是最优解。
证明:不会。这里好像有:https://yhx-12243.github.io/OI-transit/records/cf1137E.html
随着这个 \(x\) 的增加,我们发现切点会越来越向右边。于是用双指针维护即可,每次右移 \(x,y\)。
但是不知道为什么,我在打表实验时,\(y\) 取最优解时,不是 1,就是 n?
所以虽然证明用了斜率优化,但是事实上不用斜率优化,快说,谢谢 Kuroni!
Part 2
二分并列第一名的人数 \(w\)。
-
前 \(w\) 名有人得分不同。显然无解。
-
我知道前 \(w\) 名任何一个人的分数。那我就知道全部第一名人的分数了!
然后我们希望 \(xy+\sum s_i\) 尽量大,就是希望 \(\sum s_i\) 尽量大,也就是希望 \(s_i\) 的后缀和尽量大。因为 \(s_i\) 是从大到小的排序(最后一个元素最小),所以我要让低分的人尽量高分。
我们先让所有人都达到他能达到的最低分(向后看齐,比如我知道第 10 名是 50 分,第 20 名是 10 分,那么第 11~19 名都是 10 分)。然后每次找到最低名次(也就是 \(s_i\) 中能修改的最后一个元素)的人,如果他的分数可以再变高(没有向前看齐),那么就 +1。
模拟到分数总和为 \(t\)。当然如果出现【一开始就分数大于 \(t\) 了】或者【分数还没到 \(t\),就没有元素可以修改了】的情况,也会无解。
但是 \(t\le 10^{10}\) 不能直接模拟。优化就是一次不要只 +1,而是对于一个区间的元素计算一下可以加到什么就行了。
-
我不知道前 \(w\) 名任何人的分数。
我们假设第 0 名的分数是 +inf(就像ljy的whk一样),给第一名一个上界。
然后我们也像上一个情况一样做。但是最后本应并列第一名可能不真正并列,一些人得分是 \(x\),其他是 \(x-1\)。
那么,第一名的人们,真正得分必定是 \(x\)(如果是 \(x-1\) ,那么剩下的权值不能分给以前的人,寄了)。所以我们就知道了第一名的真正分数:\(x\)。重新进行
check
即可。
最后我们二分到了 \(w\)。接着我们再二分第一名的分数是多少即可。
思考题:为什么本题满足单调性?出题人是怎么想到的?
CF986E - Prince's Problem
大套路题目。
求 \(dis(u,v)\) 而且是相乘,要想到答案是 \(\Large\frac{ans(1,u)*ans(1,v)}{ans(1,lca)*ans(1,fa[lca])}\)。
对于一个 \(w\) 中的一种质因数是 \(p^{t_1}\),对于一个 \(val_u\) 中的同一种质因数是 \(p^{t_2}\),那么对答案的贡献是 \(\large p^{\min(t_1,t_2)}\)。
如果将 \((p,t)\) 看作一个颜色,那么每个数字至多代表 7 种颜色,处理询问时只用看看每种颜色有多少个即可。所以我们把询问挂在树的每一个点上,dfs 的时候增删颜色即可。