洛谷P4319 变化的道路
题意:给定图,每条边都有一段存在时间。求每段时间的最小生成树。
解:动态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 变化的道路的更多相关文章
- 洛谷 P4319 变化的道路 解题报告
P4319 变化的道路 题目描述 小 w 和小 c 在 H 国,近年来,随着 H 国的发展,H 国的道路也在不断变化着 根据 H 国的道路法,H 国道路都有一个值 \(w\),表示如果小 w 和小 c ...
- 【刷题】洛谷 P4319 变化的道路
题目描述 小 w 和小 c 在 H 国,近年来,随着 H 国的发展,H 国的道路也在不断变化着 根据 H 国的道路法,H 国道路都有一个值 \(w\) ,表示如果小 w 和小 c 通过这条道路,那么他 ...
- 洛谷P1462 通往奥格瑞玛的道路(二分+spfa,二分+Dijkstra)
洛谷P1462 通往奥格瑞玛的道路 二分费用. 用血量花费建图,用单源最短路判断 \(1\) 到 \(n\) 的最短路花费是否小于 \(b\) .二分时需要不断记录合法的 \(mid\) 值. 这里建 ...
- 洛谷P1462-通往奥格瑞玛的道路-二分+最短路
洛谷P1462-通往奥格瑞玛的道路 题目描述 在艾泽拉斯,有\(n\)个城市.编号为\(1,2,3,...,n\). 城市之间有\(m\)条双向的公路,连接着两个城市,从某个城市到另一个城市,会遭到联 ...
- 【题解】洛谷P2296 [NOIP2014TG] 寻找道路(SPFA+DFS)
题目来源:洛谷P2296 思路 一开始看还以为是一道水题 虽然本来就挺水的 本道题的难点在于如何判断是否路径上的点都会直接或者间接连着终点 我们需要在一开始多建一个反向图 然后从终点DFS回去 把路径 ...
- 洛谷 P1462 通往奥格瑞玛的道路
洛谷 题意:要求在限定油耗内,求最小花费的最大值. 求最小值最大很容易想到二分答案.所以我们往二分的方向去想. 我们二分一个费用,然后要保证到终点时满足限定油耗,所以跑最短路. 不过松弛条件要改一下: ...
- 【洛谷P4319】 变化的道路 线段树分治+LCT
最近学了一下线段树分治,感觉还蛮好用... 如果正常动态维护最大生成树的话用 LCT 就行,但是这里还有时间这一维的限制. 所以,我们就把每条边放到以时间为轴的线段树的节点上,然后写一个可撤销 LCT ...
- 洛谷 P1462 通往奥格瑞玛的道路 解题报告
P1462 通往奥格瑞玛的道路 题目背景 在艾泽拉斯大陆上有一位名叫歪嘴哦的神奇术士,他是部落的中坚力量 有一天他醒来后发现自己居然到了联盟的主城暴风城 在被众多联盟的士兵攻击后,他决定逃回自己的家乡 ...
- 【洛谷P1272】 重建道路
重建道路 题目链接 一场可怕的地震后,人们用N个牲口棚(1≤N≤150,编号1..N)重建了农夫John的牧场.由于人们没有时间建设多余的道路,所以现在从一个牲口棚到另一个牲口棚的道路是惟一的.因此, ...
随机推荐
- python之路--线程的其他方法
一 . current_thread的用法 import threading import time from threading import Thread, current_thread def ...
- 压测工具使用(vegeta)
一.压测工具vegeta 1.介绍 Vegeta 是一个用 Go 语言编写的多功能的 HTTP 负载测试工具,它提供了命令行工具和一个开发库. 官方地址:https://github.com/tsen ...
- Windows 10 & change DNS
Windows 10 & change DNS https://www.windowscentral.com/how-change-your-pcs-dns-settings-windows- ...
- QTP键盘操作笔记
micCtrlDwn Presses the Ctrl key. micCtrlUp Releases the Ctrl key. micLCtrlDwn Presses the left Ct ...
- jaxp的dom方式操作(查找、添加、修改、删除、遍历节点)
package cn.itcast.jaxptest; import java.io.IOException; import javax.xml.parsers.DocumentBuilder;imp ...
- Lodop获取全部JS代码,传统JS模版的生成
Lodop模版有两种方法,一种是传统的JS语句,可以用JS方法里的eval来执行,一种是文档式模版,是特殊格式的base64码,此篇博文介绍传统JS模版的生成方法.两种模版都可以存入一下地方进行调用, ...
- 使用电脑adb给Essential Phone刷机 —(官方篇)
用ADB给Essential Phone线刷升级 重要:请确保在刷机前已经解锁,关于解锁教程群里有! 准备 原版boot Twrp boot Magisk卡刷包 到官网下载OTA包 准备好Essent ...
- CSS3之box-sizing属性
box-sizing本身有三个属性:content-box(默认).border-box和padding-box. content-box:border与padding均不算入width中: bord ...
- 为AI提供数据:构建2017数据创新的总结
本周在微软年度大会上,我们正在讨论组织如何依靠开发人员创造突破性的经验.随着大数据,云和人工智能的融合,创新与破坏正在加速,从未见过.数据是这一融合核心的关键战略资产.当结合云的无限计算能力和机器学习 ...
- Rest模式get,put,post,delete含义与区别
POST /uri 创建 DELETE /uri/xxx 删除 PUT /uri/xxx 更新或创建 GET /uri/xxx 查看 GET操作是安全的.所谓 ...