洛谷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的牧场.由于人们没有时间建设多余的道路,所以现在从一个牲口棚到另一个牲口棚的道路是惟一的.因此, ...
随机推荐
- Mybatis+Spring整合后Mapper测试类编写
public class UserMapperTest { private ApplicationContext applicationContext; @Before public void ini ...
- Day 4-9 subprocess模块
我们经常需要通过Python去执行一条系统命令或脚本,系统的shell命令是独立于你的python进程之外的,每执行一条命令,就是发起一个新进程,通过python调用系统命令或脚本的模块在python ...
- 前K个高频元素
给定一个非空的整数数组,返回其中出现频率前 k 高的元素. 示例 1: 输入: nums = [1,1,1,2,2,3], k = 2 输出: [1,2] 示例 2: 输入: nums = [1], ...
- python之路--网络通信协议
一 . osi七层协议 互联网协议按照功能不同分为osi七层或tcp/ip五层或tcp/ip四层 二 . tcp三次握手和四次挥手 我们知道网络层,可以实现两个主机之间的通信.但是这并不具体,因为,真 ...
- django rest framework批量上传图片及导入字段
一.项目需求 批量上传图片,然后批量导入(使用excel)每个图片对应的属性(属性共十个,即对应十个字段,其中外键三个). 二.问题 一次可能上传成百上千张图片和对应字段,原来数据库的设计我将图片和对 ...
- pycharm 安装
pycharm 1.模板 file->setting->Editor->file and code template->python script->右上方 #!/usr ...
- python数据结构与算法第九天【选择排序】
1.选择排序的原理 2.代码实现 def selection_sort(alist): n = len(alist) # 需要进行n-1次选择操作 for i in range(n-1): # 记录最 ...
- python数据结构与算法第三天【时间复杂度计算方法】
最优时间复杂度(不可靠) 最坏时间复杂度(保证) 平均时间复杂度(平均状况) 不同语句的时间复杂度: (1)顺序语句:使用加法 (2)循环语句:使用乘法 (3)分支语句:使用坏时间复杂度 例如:如下代 ...
- 一个好玩的小制作,以及在<a/>中的标签href="javascript:;"/href="javascript:void(0);"/href="javascript:"的用法
一:一个小图标的制作 我们在支付宝.微信等某些地方上传文件时会遇到以下的图标,但是这样的图标其实可以用<a/>标签以及css样式完成, 具体代码如下: <!DOCTYPE html& ...
- webpack始出来
一直想好好整理一下webpack,现在就整理吧. 总结自己的实际搭建的整理情况,我还是要先对自己说一句,以后给文件夹起名字的时候不要用一些特殊的关键字,比如我在做这个demo的时候,我用的文件夹名称叫 ...