洛谷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的牧场.由于人们没有时间建设多余的道路,所以现在从一个牲口棚到另一个牲口棚的道路是惟一的.因此, ...
随机推荐
- php 将数组转换网址URL参数
$array =array ( 'id' =123, 'name' = 'dopost' );echo http_build_query( $array );//得到结果id=123name=dopo ...
- Fiddler 学习笔记---命令、断点
输入命令框: 1 输入 ?51testing 高亮显示对应记录 2 >10 选择body大于10的记录 3 <10 选择body<10的记录 4 =200 选择result=200 ...
- WEB相关概念、Tomcat初识、Servlet、基本知识。
/* * 一.web的概念? * 1.web就是在http协议基础之上, 利用浏览器进行访问的网站. * Web Page指网站内的网页. 我们常说的WWW(World Wide Web 万维网)就是 ...
- 一、linux扩展
1.linux-解压bz2文件提示tar (child): bzip2: Cannot exec: No such file or directory 原因,linux下没有bzip2解压工具 安装b ...
- Python——Radiobutton,Checkbutton参数说明
anchor : 文本位置: background(bg) : 背景色: foreground(fg) :前景色: borderwidth : 边框宽度: width : 组件的宽度: hei ...
- github上传时出现error: src refspec master does not match any解决办法22
1 error:src refspec master does not match any这个问题,我之前也遇到过,这次又遇到了只是时间间隔比较长了,为了防止以后再遇到类似问题,还是把这个方法简单记录 ...
- ASP.NET MVC和Web API中的Angular2 - 第2部分
下载源码 内容 第1部分:Visual Studio 2017中的Angular2设置,基本CRUD应用程序,第三方模态弹出控件 第2部分:使用Angular2管道进行过滤/搜索,全局错误处理,调试客 ...
- hdu-5687(字典树)
题意:中文题: 解题思路:增加和查询就不说了,标准操作,就是删除操作:删除操作的时候,我们把给定字符串先在字典树中遍历一遍,然后算出这个字符串最后一个字符的出现次数,然后在遍历一遍,每个节点都减去这个 ...
- linux下如何安装mysql和redis
linux下如何安装mysql(mariadb) linux下如何安装软件? 1. yum安装软件也得注意,一个是配置yum源 1.我们当前的是阿里云的yum源(下载速度特别快) 通过 yum ins ...
- Git——Git的简单介绍【一】
官方网站 Git官网 https://git-scm.com/ GitHub https://github.com GitLab https://about.gitlab.com/ SVN https ...