T1
暴力50分:
跑k次没有写错的dij
看起来似乎是个树
也有可能是森林
也许我们可以把它当树做
正解:
我们枚举两个距离最近的点的编号
既然两个的int表示不同,就说明它们的二进制表示上至少有一位不同。
假设枚举到第i位,就把这一位为1的点设置为源点,这一位为0的点设置成汇点
然后跑多源多汇最短路
就是设置一个超级源点s,一个超级汇点t
s向每个源点连边权为0的边,所有汇点向t连边权为0的边,然后跑单源最短路
T2:
处理到达的最大的权值(bfs)(不是dfs)
tarjan缩一波点,来个DAG上dp
代码咕咕咕
T3
暴力:
既然有20%的数据是颜色种类不超过5,所以我们可以开5棵线段树
丧心病狂的我开了100棵线段树
真好
100棵线段树的建树优化
不是for(1~100)
而是for c[l]到c[r]
这样复杂度就是O(nlogn)的了
莫得强制在线
把所有操作都读入进来
修改:从颜色1的集合中删除,从颜色2的集合中加入
所以按照颜色顺序,时间顺序处理每个操作
这样就只需要一棵线段树了
不用树链剖分:
考虑树上的某个节点的权值加x,并且要计算一个点到根的路径上的点权之和
当u+x之后,u的子树里的点到根的路径上的点权之和都+x。
如果不用树链剖分,就跑一遍普通的dfs序。
普通的dfs序保证一个点的子树是这个点出现的第一次和第三次之间的区间
我们依旧用线段树来维护区间和。
当点u的权值+x之后,在线段树上,整个区间的答案都+x
求u到v路径上的点权之和:u到根+v到根的-2*lca到根的+lca的
先这样吧qwq