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 ...
随机推荐
- 第一个django项目-通过命令行和pycharm两种方式
以本机环境为例,ip地址为172.20.16.148,windows平台,虚拟环境路径为d:\VirtualEnv,项目存放位置为d:\DjangoProject 命令行方式 1.进入虚拟环境创建项目 ...
- Builgen 插件——IntelliJ IDEA和Eclipse Java Bean Builder模式代码生成器-比lombok更符合需求
builder模式在越来越多的项目中使用,类似于alibaba fastjson JSONObject.fluentPut(),调用一个方法后返回这个对象本身,特别适合构建一些参数超级多的对象,代码优 ...
- thinkphp5 tp5 与 nginx 搭配在根目录和子目录中如何设置伪静态
配置文件参考一下: location /public/ { if (!-e $request_filename){ rewrite ^/public/(.*)$ /public/index.php?s ...
- 20145208 蔡野 《网络对抗》免考项目 MSF学习
20145208 蔡野 <网络对抗>免考项目 MSF Exploit模块开发 题目:MSF Exploit模块开发 摘要 本免考项目的目标是通过对msf模块的设计语言--ruby和expl ...
- Bugku-CTF之web基础$_GET
Day3 web基础$_GET http://123.206.87.240:8002/get/ 打开之后是一段代码
- HihoCoder 1236 Scores - bitset - 分块
Kyle is a student of Programming Monkey Elementary School. Just as others, he is deeply concerned wi ...
- Django缓存系统
在动态网站中,用户每次请求一个页面,服务器都会执行以下操作:查询数据库,渲染模板,执行业务逻辑,最后生成用户可查看的页面. 这会消耗大量的资源,当访问用户量非常大时,就要考虑这个问题了. 缓存就是为了 ...
- 并发 ---- 6. IO 多路复用
一.阻塞IO 1.代码示例 2.图形示例: 二.非阻塞IO 设置不阻塞(server.setblocking(False)),利用 try...except. 当被阻塞时, 执行except 事件, ...
- Actions对Element的一些操作解析
针对Chrome浏览器: 在自动化测试的编写中如果报出Element is not visible to click at xxxx point时,我会使用: new Actions(WebDrive ...
- 【做题】CF119D. String Transformation——KMP
题意:有两个字符串\(a,b\),下标从\(0\)开始.求数对\((i,j)\)满足\(a[i+1:j] + r(a[j:n]) + r(a[0:i+1]) = b\),其中\(r(s)\)表示字符串 ...