题意:给定图,每条边都有一段存在时间。求每段时间的最小生成树。

解:动态MST什么毒瘤...洛谷上还是蓝题...

线段树分治 + lct维护最小生成树。

对时间开线段树,每条边的存在时间在上面会对应到logn个区间。

我们先把这些边加到线段树对应节点上,但是不在lct上面加。最后扫一遍线段树。

扫到一个节点的时候把当前节点上的边加入lct,同时记录做了什么操作。回溯的时候还原操作。

最小生成树的权值不用lct维护子树和,直接用一个变量,加边删边的时候跟着修改即可。

这样复杂度就是nlog2n的...虽然常数上天了。

注意一下就是,回溯操作的时候顺序必须严格倒序。否则会出现一些情况导致re。

 #include <cstdio>
#include <algorithm>
#include <vector> typedef long long LL;
const int N = , lm = ; int fa[N], s[N][], large[N], p[N], top;
bool rev[N];
LL val[N]; inline void pushup(int x) {
large[x] = x;
if(s[x][] && val[large[x]] < val[large[s[x][]]]) {
large[x] = large[s[x][]];
}
if(s[x][] && val[large[x]] < val[large[s[x][]]]) {
large[x] = large[s[x][]];
}
return;
} inline void pushdown(int x) {
if(rev[x]) {
std::swap(s[x][], s[x][]);
if(s[x][]) {
rev[s[x][]] ^= ;
}
if(s[x][]) {
rev[s[x][]] ^= ;
}
rev[x] = ;
}
return;
} inline bool no_root(int x) {
return (s[fa[x]][] == x) || (s[fa[x]][] == x);
} inline void rotate(int x) {
int y = fa[x];
int z = fa[y];
bool f = (s[y][] == x); fa[x] = z;
if(no_root(y)) {
s[z][s[z][] == y] = x;
}
s[y][f] = s[x][!f];
if(s[x][!f]) {
fa[s[x][!f]] = y;
}
s[x][!f] = y;
fa[y] = x; pushup(y);
return;
} inline void splay(int x) {
int y = x;
p[++top] = y;
while(no_root(y)) {
y = fa[y];
p[++top] = y;
}
while(top) {
pushdown(p[top]);
top--;
} y = fa[x];
int z = fa[y];
while(no_root(x)) {
if(no_root(y)) {
(s[z][] == y) ^ (s[y][] == x) ?
rotate(x) : rotate(y);
}
rotate(x);
y = fa[x];
z = fa[y];
}
pushup(x);
return;
} inline void access(int x) {
int y = ;
while(x) {
splay(x);
s[x][] = y;
pushup(x);
y = x;
//printf("fa %d = %d \n", x, fa[x]);
x = fa[x];
}
return;
} inline void make_root(int x) {
access(x);
splay(x);
rev[x] = ;
return;
} inline int find_root(int x) {
access(x);
splay(x);
while(s[x][]) {
x = s[x][];
pushdown(x);
}
return x;
} inline void link(int x, int y) {
//printf("link %d %d \n", x, y);
make_root(x);
fa[x] = y;
return;
} inline void cut(int x, int y) {
//printf("cut %d %d \n", x, y);
make_root(x);
access(y);
splay(y);
s[y][] = fa[x] = ;
pushup(y);
return;
} inline int getMax(int x, int y) {
make_root(x);
access(y);
splay(y);
return large[y];
}
// lct OVER struct Edge {
int u, v;
LL val;
Edge(int x = , int y = , LL z = ) {
u = x;
v = y;
val = z;
}
}edge[N]; struct Node {
bool f; // 0 link 1 cut
int x;
Node(bool F = , int X = ) {
f = F;
x = X;
}
}; std::vector<int> id[N];
std::vector<Node> v[N];
int n;
LL Sum; void add(int L, int R, int v, int l, int r, int o) {
if(L <= l && r <= R) {
id[o].push_back(v);
return;
}
int mid = (l + r) >> ;
if(L <= mid) {
add(L, R, v, l, mid, o << );
}
if(mid < R) {
add(L, R, v, mid + , r, o << | );
}
return;
} void solve(int l, int r, int o) {
//printf("solve %d %d %d \n", l, r, o);
for(int i = ; i < id[o].size(); i++) {
int t = id[o][i];
int x = edge[t].u, y = edge[t].v;
int p = getMax(x, y);
if(val[p] < edge[t].val) {
continue;
}
cut(edge[p].u, p);
cut(edge[p].v, p);
link(x, t);
link(y, t);
v[o].push_back(Node(, p));
v[o].push_back(Node(, t)); // pay attention! this must be behind
Sum -= val[p];
Sum += val[t];
//printf(" > push %d %d \n", t, p);
}
if(l == r) {
printf("%lld\n", Sum + );
}
else {
int mid = (l + r) >> ;
solve(l, mid, o << );
solve(mid + , r, o << | );
}
//printf(" -- solve %d %d %d \n", l, r, o);
for(int i = v[o].size() - ; i >= ; i--) { // this must be sleep
int t = v[o][i].x;
if(v[o][i].f) {
link(edge[t].u, t);
link(edge[t].v, t);
Sum += val[t];
}
else {
cut(edge[t].u, t);
cut(edge[t].v, t);
Sum -= val[t];
}
//printf(" -- > pop %d \n", t);
}
v[o].clear();
return;
} int main() { scanf("%d", &n);
LL z;
for(int i = , x, y; i < n; i++) {
scanf("%d%d%lld", &x, &y, &z);
val[n + i] = z;
link(x, n + i);
link(n + i, y);
edge[n + i].u = x;
edge[n + i].v = y;
edge[n + i].val = z;
Sum += z;
}
int m;
scanf("%d", &m);
for(int i = , l, r; i <= m; i++) {
int t = * n + i;
scanf("%d%d%lld%d%d", &edge[t].u, &edge[t].v, &edge[t].val, &l, &r);
val[t] = edge[t].val;
add(l, r, t, , lm, );
} solve(, lm, ); return ;
}

AC代码

洛谷P4319 变化的道路的更多相关文章

  1. 洛谷 P4319 变化的道路 解题报告

    P4319 变化的道路 题目描述 小 w 和小 c 在 H 国,近年来,随着 H 国的发展,H 国的道路也在不断变化着 根据 H 国的道路法,H 国道路都有一个值 \(w\),表示如果小 w 和小 c ...

  2. 【刷题】洛谷 P4319 变化的道路

    题目描述 小 w 和小 c 在 H 国,近年来,随着 H 国的发展,H 国的道路也在不断变化着 根据 H 国的道路法,H 国道路都有一个值 \(w\) ,表示如果小 w 和小 c 通过这条道路,那么他 ...

  3. 洛谷P1462 通往奥格瑞玛的道路(二分+spfa,二分+Dijkstra)

    洛谷P1462 通往奥格瑞玛的道路 二分费用. 用血量花费建图,用单源最短路判断 \(1\) 到 \(n\) 的最短路花费是否小于 \(b\) .二分时需要不断记录合法的 \(mid\) 值. 这里建 ...

  4. 洛谷P1462-通往奥格瑞玛的道路-二分+最短路

    洛谷P1462-通往奥格瑞玛的道路 题目描述 在艾泽拉斯,有\(n\)个城市.编号为\(1,2,3,...,n\). 城市之间有\(m\)条双向的公路,连接着两个城市,从某个城市到另一个城市,会遭到联 ...

  5. 【题解】洛谷P2296 [NOIP2014TG] 寻找道路(SPFA+DFS)

    题目来源:洛谷P2296 思路 一开始看还以为是一道水题 虽然本来就挺水的 本道题的难点在于如何判断是否路径上的点都会直接或者间接连着终点 我们需要在一开始多建一个反向图 然后从终点DFS回去 把路径 ...

  6. 洛谷 P1462 通往奥格瑞玛的道路

    洛谷 题意:要求在限定油耗内,求最小花费的最大值. 求最小值最大很容易想到二分答案.所以我们往二分的方向去想. 我们二分一个费用,然后要保证到终点时满足限定油耗,所以跑最短路. 不过松弛条件要改一下: ...

  7. 【洛谷P4319】 变化的道路 线段树分治+LCT

    最近学了一下线段树分治,感觉还蛮好用... 如果正常动态维护最大生成树的话用 LCT 就行,但是这里还有时间这一维的限制. 所以,我们就把每条边放到以时间为轴的线段树的节点上,然后写一个可撤销 LCT ...

  8. 洛谷 P1462 通往奥格瑞玛的道路 解题报告

    P1462 通往奥格瑞玛的道路 题目背景 在艾泽拉斯大陆上有一位名叫歪嘴哦的神奇术士,他是部落的中坚力量 有一天他醒来后发现自己居然到了联盟的主城暴风城 在被众多联盟的士兵攻击后,他决定逃回自己的家乡 ...

  9. 【洛谷P1272】 重建道路

    重建道路 题目链接 一场可怕的地震后,人们用N个牲口棚(1≤N≤150,编号1..N)重建了农夫John的牧场.由于人们没有时间建设多余的道路,所以现在从一个牲口棚到另一个牲口棚的道路是惟一的.因此, ...

随机推荐

  1. springboot+ELK+logback日志分析系统demo

    之前写的有点乱,这篇整理了一下搭建了一个简单的ELK日志系统 借鉴此博客完成:https://blog.csdn.net/qq_22211217/article/details/80764568 设置 ...

  2. Vue 获得所选中目标的状态(checked)以及对应目标的数据,并进行相应的操作

    一.我们现在要拿取购物车中选中商品的状态和该商品的所有数据或者id <ul v-if="shopList.list.length>0"> <li class ...

  3. Android——Activity的简绍

    Activity Activity的运行机制其实和JavaEE中的servlet很像,而我们的Android系统也就相当与其servlet容器,Activity在其中进行创建实例.初始化.运行.销毁等 ...

  4. mysql “Too many connections” 解决办法

    今天生产服务器上的MySQL出现了一个不算太陌生的错误“Too many connections”.平常碰到这个问题,我基本上是修改/etc/my.cnf的max_connections参数,然后重启 ...

  5. Lodop纯文本英文-等符号自动换行问题

    ADD_PRINT_TEXT纯文本,宽度不够,高度足够,超宽会自动换行,高度不够会隐藏后面的内容.在超宽自动换行的时候,如果有-或()之类的,英文单词不拆分,或其他一些认为是不拆分的情况,会造成还没有 ...

  6. <resultMap>中 <collection>的使用

    public class Question implements Serializable { private int id; //问题Id private int accountId; //用户id ...

  7. [BZOJ 2705] [SDOI 2012] Longge的问题

    Description Longge的数学成绩非常好,并且他非常乐于挑战高难度的数学问题.现在问题来了:给定一个整数 \(N\),你需要求出 \(\sum gcd(i, N)(1\le i \le N ...

  8. 洛谷P2858奶牛零食 题解

    题目 这个题一开始能看出来是一道动态规划的题目,但是并不知道如何写状态转移方程,但是我们可以想一想这个题应该是一道区间DP,而区间DP的特点就是状态转移方程一般跟该区间的左节点和右节点或者中间断点有关 ...

  9. RMQ--ST表

    RMQ即区间最值查询,是指这样一个问题:对于长度为n的数列A,回答若干询问RMQ(A,i,j)(i,j<=n),返回数列A中下标在i,j之间的最小/大值. ST表既ST算法是一个非常有名的在线处 ...

  10. win10安装MySql 5.7.23

    下载安装 因为Django2.1不再支持MySQL5.5,这里需要重新安装一下MySQL 首先去官网下载 这里使用的是msi版本 https://dev.mysql.com/downloads/win ...