FZU 2082 过路费(树链剖分 边权)题解
题意:给出每条边权值,可以更新每条边权值,询问两个点路径的最小权值
思路:重链剖分边权化点权,让每个儿子节点继承边权。
插点权的时候比较边的两个节点的深度,插进儿子节点中。
代码:
#include<cmath>
#include<set>
#include<map>
#include<queue>
#include<cstdio>
#include<vector>
#include<cstring>
#include <iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int maxn = 50000 + 5;
const int M = 50 + 5;
const ull seed = 131;
const int INF = 0x3f3f3f3f;
const int MOD = 1000000007;
int fa[maxn];
int top[maxn];
int sz[maxn];
int son[maxn];
int deep[maxn];
int dfn[maxn], tol;
int fd[maxn]; int n, m;
struct Edge{
int v, w, id, next;
}edge[maxn << 1];
int head[maxn], tot;
void init(){
memset(head, -1, sizeof(head));
tot = tol = 0;
memset(son, -1, sizeof(son));
}
void addEdge(int u, int v, int w, int id){
edge[tot].v = v;
edge[tot].w = w;
edge[tot].id = id;
edge[tot].next = head[u];
head[u] = tot++;
}
void dfs1(int u, int pre, int d){
deep[u] = d;
fa[u] = pre;
sz[u] = 1;
for(int i = head[u]; i != -1; i = edge[i].next){
int v = edge[i].v;
if(v == pre) continue;
dfs1(v, u, d + 1);
sz[u] += sz[v];
if(son[u] == -1 || sz[v] > sz[son[u]])
son[u] = v;
}
}
void dfs2(int u, int tp){
top[u] = tp;
dfn[u] = ++tol;
fd[tol] = u;
if(son[u] == -1) return;
dfs2(son[u], tp);
for(int i = head[u]; i != -1; i = edge[i].next){
int v = edge[i].v;
if(v != son[u] && v != fa[u]){
dfs2(v, v);
}
}
} ll sum[maxn << 2];
void update(int pos, int l, int r, int v, int rt){
if(l == r){
sum[rt] = v;
return;
}
int m = (l + r) >> 1;
if(pos <= m)
update(pos, l, m, v, rt << 1);
else
update(pos, m + 1, r, v, rt << 1 | 1);
sum[rt] = sum[rt << 1] + sum[rt << 1 | 1];
}
ll query(int L, int R, int l, int r, int rt){
if(L <= l && R >= r){
return sum[rt];
}
int m = (l + r) >> 1, ans = 0;
if(L <= m)
ans += query(L, R, l, m, rt << 1);
if(R > m)
ans += query(L, R, m + 1, r, rt << 1 | 1);
sum[rt] = sum[rt << 1] + sum[rt << 1 | 1];
return ans;
} ll change(int u, int v){
ll ret = 0;
while(top[u] != top[v]){
if(deep[top[u]] < deep[top[v]]) swap(u, v);
ret += query(dfn[top[u]], dfn[u], 1, n, 1);
u = fa[top[u]];
}
if(u == v) return ret; //!!!
if(deep[u] > deep[v]) swap(u, v);
ret += query(dfn[son[u]], dfn[v], 1, n, 1);
return ret;
}
int e[maxn][3];
int main(){
while(~scanf("%d%d", &n, &m)){
init();
for(int i = 1; i <= n - 1; i++){
int u, v, w;
scanf("%d%d%d", &u, &v, &w);
addEdge(u, v, w, i);
addEdge(v, u, w, i);
e[i][0] = u, e[i][1] = v, e[i][2] = w;
}
dfs1(1, 0, 0);
dfs2(1, 1);
for(int i = 1; i <= n - 1; i++){
int fx = e[i][0], fy = e[i][1];
if(deep[fx] < deep[fy]) swap(fx, fy);
update(dfn[fx], 1, n, e[i][2], 1);
}
while(m--){
int op, a, b;
scanf("%d%d%d", &op, &a, &b);
if(op == 0){
int fx = e[a][0], fy = e[a][1];
if(deep[fx] < deep[fy]) swap(fx, fy);
update(dfn[fx], 1, n, b, 1);
}
else{
printf("%lld\n", change(a, b));
}
}
}
return 0;
}
FZU 2082 过路费(树链剖分 边权)题解的更多相关文章
- FZU 2082 过路费 (树链剖分 修改单边权)
题目链接:http://acm.fzu.edu.cn/problem.php?pid=2082 树链剖分模版题,求和,修改单边权. #include <iostream> #include ...
- FZU 2082 过路费(树链剖分)
FZU 2082 过路费 题目链接 树链抛分改动边的模板题 代码: #include <cstdio> #include <cstring> #include <vect ...
- FZU Problem 2082 过路费 树链剖分
Problem 2082 过路费 Problem Description 有n座城市,由n-1条路相连通,使得任意两座城市之间可达.每条路有过路费,要交过路费才能通过.每条路的过路费经常会更新, ...
- BZOJ 1036 [ZJOI2008]树的统计Count (树链剖分 - 点权剖分 - 单点权修改)
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1036 树链剖分模版题,打的时候注意点就行.做这题的时候,真的傻了,单词拼错检查了一个多小时 ...
- 计蒜客 38229.Distance on the tree-1.树链剖分(边权)+可持久化线段树(区间小于等于k的数的个数)+离散化+离线处理 or 2.树上第k大(主席树)+二分+离散化+在线查询 (The Preliminary Contest for ICPC China Nanchang National Invitational 南昌邀请赛网络赛)
Distance on the tree DSM(Data Structure Master) once learned about tree when he was preparing for NO ...
- POJ3237 Tree 树链剖分 边权
POJ3237 Tree 树链剖分 边权 传送门:http://poj.org/problem?id=3237 题意: n个点的,n-1条边 修改单边边权 将a->b的边权取反 查询a-> ...
- POJ2763 Housewife Wind 树链剖分 边权
POJ2763 Housewife Wind 树链剖分 边权 传送门:http://poj.org/problem?id=2763 题意: n个点的,n-1条边,有边权 修改单边边权 询问 输出 当前 ...
- HDU3669 Aragorn's Story 树链剖分 点权
HDU3669 Aragorn's Story 树链剖分 点权 传送门:http://acm.hdu.edu.cn/showproblem.php?pid=3966 题意: n个点的,m条边,每个点都 ...
- BZOJ 1984: 月下“毛景树” [树链剖分 边权]
1984: 月下“毛景树” Time Limit: 20 Sec Memory Limit: 64 MBSubmit: 1728 Solved: 531[Submit][Status][Discu ...
- SPOJ 375 (树链剖分 - 边权剖分 - 修改单边权)
题目链接:http://acm.hust.edu.cn/vjudge/contest/view.action?cid=28982#problem/I 给你一棵有边权的树,有两个操作:一个操作是输出l到 ...
随机推荐
- 【MYSQL】DDL语句
介绍:DDL语句,即数据定义语句,定义了不同的数据段,数据库表.表.列.索引等数据库对象:例如,create.drop.alter 适用对象:一般是由数据库管理员DBA使用 1.连接数据库 mysql ...
- TCP三次握手Linux源码解析
TCP是面向连接的协议.面向连接的传输层协议在原点和重点之间建立了一条虚拟路径,同属于一个报文的所有报文段都沿着这条虚拟路径发送,为整个报文使用一条虚拟路径能够更容易地实施确认过程以及对损伤或者丢失报 ...
- java进阶(33)--IO流
一.IO流概念:1.基本概念2.IO流分类3.java.io流的四大家族4.流的close和flush方法5.java.id下常用的16个流 二.FileInputStream字节输入流1.FileI ...
- 如何讲清楚 Java 面向对象的问题与知识?(类与对象,封装,继承,多态,接口,内部类...)
写在最前面 这个项目是从20年末就立好的 flag,经过几年的学习,回过头再去看很多知识点又有新的理解.所以趁着找实习的准备,结合以前的学习储备,创建一个主要针对应届生和初学者的 Java 开源知识项 ...
- Salt (cryptography)
Salt (cryptography) Here is an incomplete example of a salt value for storing passwords. This first ...
- assert False 与 try 结合 在开发中的使用
让错误抛出 发现其中的问题 # coding=utf-8 from rest_framework.views import exception_handler from rest_framework. ...
- (Oracle)DDL及其数据泵导入导出(impdp/expdp)
create tablespace ybp_dev datafile 'G:\app\Administrator\oradata\health\ybp_dev1.dbf' size 10m autoe ...
- 判断2个list中是否有相同的数据(相交)Collections.disjoint
https://blog.csdn.net/yang_niuxxx/article/details/85092490 private void initData() { for (int i = 0; ...
- Python 学习笔记(1)
Mac下载安装Python mac 系统自带有python .但就最新的mac系统而言,它自带的python版本为2.*版本. 虽然不影响对于老python项目的运行,但3.*版本中很多语法都发生了改 ...
- CSS选择器,属性前缀,长度单位,变形效果,过渡效果,动画效果
CSS3选择器 ·*通配选择器 ·E标签选择器 ·E#id ID选择器 ·E.class类选择器 ·E F包含选择器,后代选择器 ·E>F子包含选择器 ·E+F相邻兄弟选择器 ·E[foo]属性 ...