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的更多相关文章

  1. 「CF838B」 Diverging Directions

    B. Diverging Directions 题意 给出一个n个点2n-2条边的有向图.n-1条指向远离根方向的边形成一棵树,还有n-1条从非根节点指向根节点的边. q次操作,1修改第x条边权值为y ...

  2. Codeforces 838B - Diverging Directions - [DFS序+线段树]

    题目链接:http://codeforces.com/problemset/problem/838/B You are given a directed weighted graph with n n ...

  3. CodeForces 838B Diverging Directions 兼【20180808模拟测试】t3

    描述 给你一个图,一共有 N 个点,2*N-2 条有向边. 边目录按两部分给出 1. 开始的 n-1 条边描述了一颗以 1 号点为根的生成树,即每个点都可以由 1 号点到达. 2. 接下来的 N-1 ...

  4. 线段树(Segment Tree)总结

    0 写在前面 怎么说呢,其实从入坑线段树一来,经历过两个阶段,第一个阶段是初学阶段,那个时候看网上的一些教学博文和模板入门了线段树, 然后挑选了一个线段树模板作为自己的模板,经过了一点自己的修改,然后 ...

  5. 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 ...

  6. 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 ...

  7. 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. ...

  8. 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 ...

  9. 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 ...

随机推荐

  1. WEB后台认证机制

    mark to :http://www.cnblogs.com/xiekeli/p/5607107.html HTTP Basic Auth HTTP Basic Auth简单点说明就是每次请求API ...

  2. linux command wrap

    $ cat tmux-attach ] ; then tmux ls else tmux attach -t $ fi $ cat /usr/bin/cscope-go.sh #!/bin/bash ...

  3. shell 调试脚本设置

    set -x 脚本部分内容 set +x

  4. day28 网络编程

    网络编程 什么是网络编程? 编写基于网络的应用程序的过程称之为网络编程 一.CS构架 C/S构架 服务器和客户端之间用网线连接 提供数据的计算机称为服务器,访问数据的计算机称为客户端 二.网络通讯的基 ...

  5. 1.面向过程编程 2.面向对象编程 3.类和对象 4.python 创建类和对象 如何使用对象 5.属性的查找顺序 6.初始化函数 7.绑定方法 与非绑定方法

    1.面向过程编程 面向过程:一种编程思想在编写代码时 要时刻想着过程这个两个字过程指的是什么? 解决问题的步骤 流程,即第一步干什么 第二步干什么,其目的是将一个复杂的问题,拆分为若干的小的问题,按照 ...

  6. cJSON库的简单介绍及使用

    转载:http://www.cnblogs.com/liunianshiwei/p/6087596.html JSON 语法是 JavaScript 对象表示法语法的子集.数据在键/值对中:数据由逗号 ...

  7. topcoder srm 709 div1

    1 给定一个长度为n的整数数组A,重排列数组A使得下面计算出的X最大:(n不大于15,A中的大于等于0小于等于50) int X=0; for(int i=0;i<n;++i) X=X+(X^A ...

  8. 启动Activiti项目报错:org.activiti.engine.ActivitiObjectNotFoundException: no deployed process definition found with id '22501'

    背景 启动activiti项目时,出现错误org.activiti.engine.ActivitiObjectNotFoundException: no deployed process defini ...

  9. tp框架中的一些疑点知识-5

    关于vim中的缓存区的前后bp和bn的界定 通过命令ls可以看到 缓存区的 排序. 最开始打开的文件排在最上面, 序号最小. 那么它们就是 更 前 的缓冲区. 序号更前的用bp, 序号靠后的用bn. ...

  10. 推荐一个静态博客兼笔记的工具:WDTP

    简介 WDTP(山湖录)不止是一款开源免费的GUI桌面单机版静态网站生成器和简单方便的前端开发工具,更是一款跨平台的集笔记.录音.个人知识管理.写作/创作.博客/网站内容与样式管理等功能于一体的多合一 ...