Atcoder abc250
https://atcoder.jp/contests/abc250/tasks
F - One Fourth
平面凸n边形
选非相邻点切割
求min( 8 abs(size/4 - eated))
就是选一些点, 围成的凸多边形 min(8abs(size * 3/4 - 选定凸多边形 ))
只切一次!!!!!!!!!!!!!!!!!!!!
范围
n 1e5
x,y [-4e8,4e8]
2s
1024 mb
我的思路
没做过多少计算几何相关的题目
一个想法是, 假设一个点会被保留, 想做前i个点, 第i个点保留的 最大, 小于目标的面积, 但似乎没有局部性
因为看起来像有相互冲突的背包
如果不是1/4, 是1/2呢, 我似乎1/2也不会做
干,读错题, 只切一次………….
题解
一个n^2 的方法
选点i, 移动j=i+1…
然后算大小, 每次增加被切三角形的面积
加个滑窗双指针就没了
代码
https://atcoder.jp/contests/abc250/submissions/35189253
1 |
|
G - Stonks
n天, 第i天 pi
每天 可以 买1单位/卖1单位
足够多初始金钱
求最大赚的数量
范围
n 2e5
pi [1,1e9]
2s
1024mb
我的思路
显然买的次数=卖的次数
如果只有一买卖次, 那么就是维护前缀最低, ans=max(ans, 当前-前缀min)
考虑两次
如果两次的操作与第一次最优的方案都没有重叠
那么其中一组用第一次的替换不会更差
所以两次的方案, 中出现一次的操作相关的也可以得到最优答案
但是并不好拆
一个复杂度明显会超的dp是
dp[i][j]
= 前i个, 持有j个
转移dp[i][j] = max(dp[i-1][j], j>0 && dp[i-1][j-1]-a[i],dp[i-1][j+1]+a[i])
最后答案 = dp[i][0]
再就是, 作为卖的价格, 都是尽量选大的, 而买的价格都是尽量小的
有没有可能 从值考虑去看范围
但是例如 3 4 1 2
, 就会出现有的买比卖还大
然后就是能不能贪心
每次获得最大的
然后在这个前面中找最小的, 做成一对产生收益, 都删掉
如此重复?
这样的话, 线段树一类可以维护+查询
问题是是否有正确性
1 3 2 4
, 显然能产生代价为4, 而不是3
考虑剩下的未被选的
显然是一个单调递减的序列
考虑说前i-1个如果通过了两两配对达到了最大, 那么剩余的就是一个单调递减序列
现在多一个a[i] 对答案会有什么影响
3 1 2 4
, 最大是3
再一个就是 上面可以看到 就是给一个前缀和 >= 0 的 1/0/-1序列和 a[i]的乘积最大
题解
也是上来, 和我一样的一个n^2 dp
然后说把dp看成二维表, 考虑 做一些列上的处理
例如输入
1 | 8 |
会有
1 | 0 -2 |
做dp[i][j-1]-dp[i][j]
, 有
1 | 2 |
题解要我观察, 我啥都没观察出, 只看出这些数都是来自 输入的元素
记录所有可以贡献的点
那么增加a[i],找最小的小于a[i] 可连接的, 如果前面
如果是没匹配的,y < a[i], 则(y,a[i]) 构成一对
x < y < a[i]
那么, (x,a[i]) 成一组, y单独 拎出来 等待匹配, 而两种做法, a[i] 都是未来可以匹配的
所以如果一个点z成为卖出, 那它还可以成为两次
买入, (x,y) + z = (x,z) + y => (x,?) +z => (z,!)
如果一个点没有成为卖出,那它还可以成为 一次 买入
proof
横坐标j, 纵坐标dp[i][j]
画曲线
考虑dp[i]
的曲线 如何变到dp[i+1]
的曲线
注意到上面的转移方程dp[i][j] = max(dp[i-1][j],dp[i-1][j-1]-A[i],dp[i-1][j+1]+A[i])
黑色为dp[6], 蓝色为 max第二项, 红色为max第三项
然后证明, dp和dp+, 一部分是dp大一部分是dp+大, dp和dp-也是, 且结果还是上凸
并且分割的位置,就是 斜率 -a[i] 处
???????? 没看懂这说的和上面的操作之间的关系, 怎么就证明了
代码
https://atcoder.jp/contests/abc250/submissions/35191923
1 |
|
Ex - Trespassing Takahashi
n 个点, m 边的路, 第i条需要ci分钟, 连通图
其中k个点是可以休息的
对于q个询问,ti从小到大
从任意可休息点移动时间不能超过ti, 到达任意一个休息点后把累计移动时间清零, 问他能否从休息点xi开始走到达休息点yi
范围
k,n 2e5
m 2e5
ci [1,1e9]
q 2e5
ti 1e15
7s
1024mb
我的思路
对于不同的Q来说, 有xi,yi,ti 3个变量
ti既然给的就是从小到大,那么休息点之间的并查集关系也是逐渐合并的
一个TLE的方法是
求休息点之间的距离建立并查集, 然后看xi和yi是否同一个并查集
问题是, 难以低复杂度求两两之间的最短距离,
题解
也是一样考虑k个点的图G,两两之间是距离, 然后上并查集 需要 O(k^2)
优化
假设T是G的最小生成树, 那么T的答案和G等价
proof
显然最小生成树过程中 都是将两个不同的连通块连在一起,用当前可用的最短边, 所以现在问题是<=ti的边能否把一些点连成同一个连通块,
当<=ti让u和v不在同一个连通块时, 显然最小生成树上u到v的路径也有> ti的边,
而当<=ti让u和v在同一连通块时,
对<=ti的边染色为黑色, > ti的边染色为白色
重新考虑T的生成过程, 如果有任意黑色边能让两个不连通的块连通之前,不会选任何白色, 因此在选白色之前, u和v就已经连通了,所以最小生成树上问题等价
以上证明了只需要k-1条边, 但如何找呢
Borůvka 算法, 相当于 多源Prim
对于现在的每个连通块,找到从这个连通块出发,不在最小生成树中的、到达别的连通块的最短边。(相等的边增加额外顺序, 避免A-1-B-1-C-1-A这种形成环,也可以并查集保护)
把这些边全部加入最小生成树中
每次O(M) 但是每次联通块个数减半, 所以O(ElogV)
另一个方法
u-a-b-v
= (u-a-b)-(v)
可以由 (u-..-a)的最短 +(a-b) + (b-..-v)的最短
然后所有休息点做多源 dij
计算每个点 到 最近的休息点的 距离和是哪个点
a-1-?-2-b, ?-3-c
的话,不会计算b-c的距离, 只会计算
a-b: (a-?)+(?-b)+(b-b)
a-c: (a-?)+(?-c)+(c-c)
proof
这个相当于是从边是否经过的角度考虑
如果经过边i, 当前限制为t, 如果 ci+ d[a_i]+d[b_i] > t (也就是经过这个边的最近的两个点都超过t) 那么这个边一定不经过
否则 链接 最近的两个点
又两个d至少一个小于t/2
所以对于一侧来讲,归纳显然相当于一侧全连通(因为只关心并查集关系,不关系具体边)
例如t=15, 那么a的一侧一定全连通
a'-1-a-1-b-10-b'
而对于右侧 a'-1-a-1-b-11-b''
向这种, 那么就是取b-…-b’’ 路径上的边 b-?
要么是(a’-b) + (b-?) + (?-b’’)
要么是(b’-b) + (b-?) + (?-b’’)
因为b的最近点只可能是a’或者b’, 所以如果合法依然连通
得证
这样找的距离 产生的图, 的<=t的联通性不变
代码
https://atcoder.jp/contests/abc250/submissions/35205404
1 |
|
总结
F
不要读错题,不要读错题,不要读错题,不要读错题,不要读错题
还是先考虑多项式暴力方法再转换, 然后就滑窗呗
G
贪心也感觉没证明, 证明也没看懂有啥关系
Ex
最小生成树 一般都写的Kursukal,基本没写过Prim(一个点开始不断贪心扩最短边), 更不要说 Borůvka’s
这个 u-a-b-v 的想法, 感觉有点像找直径时候的中间的点的想法, 这<= t的连通性 等价证明