Atcoder abc301
https://atcoder.jp/contests/abc301/tasks
G Worst Picture
三维空间 n个人, 整点坐标(xi > 0,yi,zi), 两两坐标不同
需要选点p(x<0,y,z) , 在 x正向拍照
p,A,B共线,则后面的人不被拍到
想办法找点p 让被拍到的人的人尽量小, 求最小被拍到的人
n 50
x [1,1000]
y,z [-1000,1000]
4s
1024mb
我的思路
二维空间几何都还不熟,这里来个3维的
但为什么看起来 逻辑很简单,只是实现不知道
既然N 只有50, 那么就是 暴力选4个点, 这样两条线找交点
这样再去枚举交点
一个特殊情况是有一条线上 有很多点,那么这条线上任意一个位置都可以
那么问题来了,如何找三维空间中的交点
感觉就是先抛弃 第3维,直接计算(x,y)的交点, 再验证z?
似乎卡着时间过了, 一次TLE一个点,一次AC
代码
https://atcoder.jp/contests/abc301/submissions/42097253
1 |
|
Ex Difference of Distance
无向n点,m边(有边权w)连通图
d(s,t) = min( s到t的路径的最重的边)
q个独立询问, 若边 ai 权重+=1, d(Si,Ti) 是否会增加
n 2e5
m 2e5
wi [1,m]
q 2e5
5s
1024mb
我的思路
首先是增加ai权重+1,那么原来的 min( s=>t) 如果没有经过 ai, 则 它不变,而 经过了ai的,如果ai不是最大值,也不会变,而经过ai且ai的权重是最大值,这条路径上才会变
所以实际的问题是:
- 当前
d(Si,Ti) = weight[ai]
, 因为如果不等,更小就是有不经过它的,更大就是即使经过它它也不是最大的 - 是否存在一个不经过
ai
且=d(Si,Ti)
的路径
并不可做
换个角度,单次直接查询呢?
那就是从S 做dij, ans[u][vis = true/false]
Si到达u 是否经过边ai, 的最小代价
而实际就是看
ans[Ti][true]
是否为 weight[ai]
以及
ans[Ti][false]
是否为 weight[ai]
, (不可达记为INF, 但不可达只是说明会经过并不表示一定有贡献)
而dij 实际每次是已经到达的点 的延伸的 最小权重的边
这看上去是最小生成树
所以对询问按照 w[ai]
顺序离线处理
几个问题
虽然并查集能处理哪些点连通了,但是似乎没法做加了一条边以后哪些点连通了的通知
第二个是 增加 边a_q_i
是正常操作,但是不增加的话,需要对整个并查集复制一份, 这样空间肯定不够
第三个就是当 有很多边权重一样时 又和询问有关,如何控制顺序
对于前两问题,一个办法是
当要考虑a_i的影响时, 把所有weight <= w[ai]
的边都处理完
那么这个时候才去主动查询si,ti的关系,
如果连通则说明ai不会影响
如果未连通,而且ai的两头也不是si,ti对应的两个并查集,则加了ai也不连通,这样 si,ti始终会经过更大的边,也不影响
只有未连通,加了ai就连通时才会影响
如果weight两两不等还好 就解决了, 如果有相等又回到第三个问题
想法是,二分法/分治,既然有 很多条 weight = w[ai]
的边
那不妨把这些边放入数组 vector<int> edge
并查集拷贝一份 施加 edge 左半的链接,查询右半
并查集拷贝一份 施加 edge 右半的链接,查询左半
这样每次 (log(m) n)
而问题是当 只有2个时依然会拷贝整个,这样有拷贝就会 (m/2 n)
虽然上面解决了同一个weight,边很多时的情况
但是 反过来让边weight两两不同的情况变得复杂度过高
一个想法是在 做分治前把每个点做uf,然后拷贝内容只有这些相关的点和它们的root
然而加了一堆还是TLE
https://atcoder.jp/contests/abc301/submissions/42099268
题解
也是先判断 w[ai] = d(si,ti)
问题变成<= w[ai]
图中 是否有不经过ai让si,ti相连
- ai 在 si,ti 中是桥(删除后会使得连通块个数+1的边),且删除ai后 两个连通块分别有si,ti
有一个lowlink算法,能O(V+E) enumerate the bridges
这个lowlink似乎就是tarjan/scc里面用的那个算法, 在这里可以找到所有bridge
而如果,一条边是桥,那么dfs遍历时,桥的子向节点是一个子(树/图)
s,t有且只有一个属于其中, 也就是 s/t \in [in[桥],out[桥]]
且在有ai的时候s,t是连通的
代码
https://atcoder.jp/contests/abc301/submissions/42102172
1 |
|
总结
G
真难写,还是卡过的,甚至不知道怎么优化
Ex
一眼很难,仔细分析还是觉得比较显然
但是最后这优化还是卡住了
之前lowlink只在tarjan/scc里见过,原来它还可以用来找所有bridge
这样看起来我的并查集的办法 虽然每次复制点也是均摊总代价O(2m),但是复制以后的合并代价会很高???
其实也是第一次做,删了一条边s,t是否连通的问题,这也是我卡住的地方