P2936【FJ Training 2014 Day2】城市建设
问题描述
PS国是一个拥有诸多城市的大国,国王Louis为城市的交通建设可谓绞尽脑汁。Louis可以在某些城市之间修建道路,在不同的城市之间修建道路需要不同的花费。Louis希望建造最少的道路使得国内所有的城市连通。但是由于某些因素,城市之间修建道路需要的花费会随着时间而改变,Louis会不断得到某道路的修建代价改变的消息,他希望每得到一条消息后能立即知道使城市连通的最小花费总和,Louis决定求助于你来完成这个任务。
因版权问题,题目已隐藏。如有需要请私下联系root或nodgd。
输入格式
第一行包含三个整数N,M,Q,分别表示城市的数目,可以修建的道路个数,及收到的消息个数。
接下来有M行,第i+1行有三个用空格隔开的整数Xi,Yi,Zi(1<=Xi,Yi<=N, 0<=Zi<=5*107),表示在城市Xi与城市Yi之间修建道路的代价为Zi。接下来Q行,每行包含两个数k,d,表示输入的第k个道路的修建代价修改为d(即将Zi修改为d)。
输出格式
包含Q行,第i行输出得知前i条消息后使城市连通的最小花费总和。
样例输入
5 5 3
1 2 1
2 3 2
3 4 3
4 5 4
5 1 5
1 6
1 1
5 3
样例输出
14
10
9
提示
对于20%的数据, n≤1000,m≤6000,Q≤6000。
另有20%的数据,n≤1000,m≤50000,Q≤8000,修改后的代价不会比之前的代价低。
对于100%的数据, n≤20000,m≤50000,Q≤50000。
题目让维护一个边权不断变化的动态最小生成树。容易发现修改边权相当于删除一条边再添加一条边。
容易发现LCT可以轻松维护加边操作,但无法维护删边操作。
此时考虑用CDQ分治去掉删边操作。
预处理每条边存在的时间,按时间分治,每次将覆盖了整个左区间或右区间的边插入到左区间或右区间的LCT中。分治底层就是每一个时刻的答案LCT。
但是并不能开$n\log n$个LCT,空间承受不了,容易发现LCT上的操作是可以撤销的,LINK和CUT互为逆操作,因此只需要用栈记录一下操作,回溯的时候撤销就行。这样就只需要开一颗全局LCT。
最终时间复杂度$O(2m\log q\log(2n))$,加上LCT的大常数,导致这样做非常地卡常,想要通过此题需要优秀的常数。
另外本题有另一个利用MST性质的做法,大致是利用MST将边分成三类同时缩点,不断缩小边集和点集。时间复杂度一样,但常数小。
代码(常数巨大以至于不能AC):
1 |
|