Codeforces 838 B - Diverging Directions
思路:
用dfs序+线段树维护子树中距离(从1到u,再从u到1)的最小值
代码:
#pragma GCC optimize(2)
#pragma GCC optimize(3)
#pragma GCC optimize(4)
#include<bits/stdc++.h>
using namespace std;
#define fi first
#define se second
#define pi acos(-1.0)
#define LL long long
//#define mp make_pair
#define pb push_back
#define ls rt<<1, l, m
#define rs rt<<1|1, m+1, r
#define ULL unsigned LL
#define pll pair<LL, LL>
#define pii pair<int, int>
#define piii pair<pii, int>
#define mem(a, b) memset(a, b, sizeof(a))
#define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout);
//head const int N = 2e5 + ;
const LL INF = 0x3f3f3f3f3f3f3f3f;
int L[N], R[N], anc[N][], deep[N], f[N], b[N], bb[N], head[N], cnt = , now = ;
LL tree[N<<], lazy[N<<], a[N];
struct edge {
int from, to, w, nxt;
}edge[N];
void add_edge(int u, int v, int w) {
edge[cnt].from = u;
edge[cnt].to = v;
edge[cnt].w = w;
edge[cnt].nxt = head[u];
head[u] = cnt++;
} void push_up(int rt) {
tree[rt] = min(tree[rt<<], tree[rt<<|]);
}
void push_down(int rt) {
lazy[rt<<] += lazy[rt];
lazy[rt<<|] += lazy[rt];
tree[rt<<] += lazy[rt];
tree[rt<<|] += lazy[rt];
lazy[rt] = ;
}
void build(int rt, int l, int r) {
if(l == r) {
tree[rt] = a[f[l]];
return ;
}
int m = l+r >> ;
build(ls);
build(rs);
push_up(rt);
}
void update(int L, int R, int v, int rt, int l, int r) {
if(L <= l && r <= R) {
tree[rt] += v;
lazy[rt] += v;
return ;
}
if(lazy[rt]) push_down(rt);
int m = l+r >> ;
if(L <= m) update(L, R, v, ls);
if(R > m) update(L, R, v, rs);
push_up(rt);
}
LL query(int L, int R, int rt, int l, int r) {
if(L <= l && r <= R) return tree[rt];
if(lazy[rt]) push_down(rt);
int m = l+r >> ;
LL ans = INF;
if(L <= m) ans = min(ans, query(L, R, ls));
if(R > m) ans = min(ans, query(L, R, rs));
push_up(rt);
return ans;
}
void dfs(int u) {
L[u] = now;
f[now] = u;
for (int i = head[u]; ~i; i = edge[i].nxt) {
int v = edge[i].to;
anc[v][] = u;
for (int j = ; j < ; j++) anc[v][j] = anc[anc[v][j-]][j-];
deep[v] = deep[u] + ;
now++;
a[v] = a[u] - b[u] + edge[i].w + b[v];
dfs(v);
}
R[u] = now;
}
int lca(int u, int v) {
if(deep[u] < deep[v]) swap(u, v);
for (int i = ; i >= ; i--) if(deep[anc[u][i]] >= deep[v]) u = anc[u][i];
if(u == v) return u;
for (int i = ; i >= ; i--) if(anc[u][i] != anc[v][i]) u = anc[u][i], v = anc[v][i];
return anc[u][];
}
int main() {
int n, q, ty, u, v, w;
mem(head, -);
scanf("%d %d", &n, &q);
for (int i = ; i < n; i++) {
scanf("%d %d %d", &u, &v, &w);
add_edge(u, v, w);
} for (int i = ; i < n; i++) {
scanf("%d %d %d", &u, &v, &w);
b[u] = w;
bb[i] = u;
} for (int i = ; i < ; i++) anc[][i] = ;
dfs();
build(, L[], R[]);
while(q--) {
scanf("%d %d %d", &ty, &u, &v);
if(ty == ) {
if(u >= n) {
int nod = bb[u-n+];
int add = v - b[nod];
update(L[nod], L[nod], add, , L[], R[]);
b[nod] = v;
}
else {
int nod = edge[u].to;
int add = v - edge[u].w;
update(L[nod], R[nod], add, , L[], R[]);
edge[u].w = v;
}
}
else {
int l = lca(u, v);
LL ans = INF;
if(l == u) {
LL dis1 = query(L[u], L[u], , L[], R[]) - b[u];
LL dis2 = query(L[v], L[v], , L[], R[]) - b[v];
ans = dis2 - dis1;
}
else {
LL dis1 = query(L[u], R[u], , L[], R[]) - (query(L[u], L[u], , L[], R[]) - b[u]);
LL dis2 = query(L[v], L[v], , L[], R[]) - b[v];
ans = dis1 + dis2;
}
printf("%lld\n", ans);
}
}
return ;
}
Codeforces 838 B - Diverging Directions的更多相关文章
- 「CF838B」 Diverging Directions
B. Diverging Directions 题意 给出一个n个点2n-2条边的有向图.n-1条指向远离根方向的边形成一棵树,还有n-1条从非根节点指向根节点的边. q次操作,1修改第x条边权值为y ...
- Codeforces 838B - Diverging Directions - [DFS序+线段树]
题目链接:http://codeforces.com/problemset/problem/838/B You are given a directed weighted graph with n n ...
- CodeForces 838B Diverging Directions 兼【20180808模拟测试】t3
描述 给你一个图,一共有 N 个点,2*N-2 条有向边. 边目录按两部分给出 1. 开始的 n-1 条边描述了一颗以 1 号点为根的生成树,即每个点都可以由 1 号点到达. 2. 接下来的 N-1 ...
- 线段树(Segment Tree)总结
0 写在前面 怎么说呢,其实从入坑线段树一来,经历过两个阶段,第一个阶段是初学阶段,那个时候看网上的一些教学博文和模板入门了线段树, 然后挑选了一个线段树模板作为自己的模板,经过了一点自己的修改,然后 ...
- http://codeforces.com/contest/838/problem/A
A. Binary Blocks time limit per test 2 seconds memory limit per test 256 megabytes input standard in ...
- Codeforces Round #385 (Div. 2) B - Hongcow Solves A Puzzle 暴力
B - Hongcow Solves A Puzzle 题目连接: http://codeforces.com/contest/745/problem/B Description Hongcow li ...
- Codeforces Round #292 (Div. 1) C. Drazil and Park 线段树
C. Drazil and Park 题目连接: http://codeforces.com/contest/516/problem/C Description Drazil is a monkey. ...
- Codeforces Round #370 (Div. 2)B. Memory and Trident
地址:http://codeforces.com/problemset/problem/712/B 题目: B. Memory and Trident time limit per test 2 se ...
- Codeforces Beta Round #69 (Div. 1 Only) C. Beavermuncher-0xFF 树上贪心
题目链接: http://codeforces.com/problemset/problem/77/C C. Beavermuncher-0xFF time limit per test:3 seco ...
随机推荐
- 20165310 NetSec2019 Week6 Exp4 恶意代码分析
20165310 NetSec2019 Week6 Exp4 恶意代码分析 一.实验要求 1.系统运行监控 使用如计划任务,每隔一分钟记录自己的电脑有哪些程序在联网,连接的外部IP是哪里.运行一段时间 ...
- [内核驱动] 链表LIST_ENTRY的操作(转)
转载:https://www.cnblogs.com/forlina/archive/2011/08/11/2134610.html 转载:http://www.xuebuyuan.com/15443 ...
- PyCharm笔记之首次安装和激活
转载:http://www.cnblogs.com/Ivyli4258/p/7440147.html PyCharm是一种Python IDE,带有一整套可以帮助用户在使用Python语言开发时提高其 ...
- ./configure: error: C compiler cc is not found
没有安装gcc 在安装nginx之前先安装依赖软件 yum install -y gcc gcc-c++ autoconf pcre pcre-devel make automake wget htt ...
- 如何开启Intel HAXM功能
1. 启用BIOS中的Intel(R) Virtualization Technology选项 2.设置成功后,在控制台中输入sc query intelhaxm.出现下图即为成功 3. 启动andr ...
- Spring Cloud 入门指南
Spring Cloud 方志朋-史上最简单的 Spring Cloud 教程
- List of 3rd Party .NET UI & Reporting Components
https://www.codeproject.com/Reference/788434/List-of-rd-Party-NET-UI-Reporting-Components Introducti ...
- wqCms6.0在IIS6的Getshell
2017-02-15发布 一.漏洞利用点 漏洞文件:admin_UploadDataHandler.ashx 自定义构造上传点 二.hack it 三.POC <html> <bod ...
- Anaconda使用命令
参考的地址:https://zhuanlan.zhihu.com/p/32925500 conda 基础命令: 1.验证conda已被安装 conda --version 终端上就会以conda 版本 ...
- 转载:避免重复插入,更新的sql
本文章来给大家提供三种在mysql中避免重复插入记录方法,主要是讲到了ignore,Replace,ON DUPLICATE KEY UPDATE三种方法,各位同学可尝试参考. 案一:使用ignore ...