题意:给出每条边权值,可以更新每条边权值,询问两个点路径的最小权值

思路:重链剖分边权化点权,让每个儿子节点继承边权。

插点权的时候比较边的两个节点的深度,插进儿子节点中。

代码:

#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 过路费(树链剖分 边权)题解的更多相关文章

  1. FZU 2082 过路费 (树链剖分 修改单边权)

    题目链接:http://acm.fzu.edu.cn/problem.php?pid=2082 树链剖分模版题,求和,修改单边权. #include <iostream> #include ...

  2. FZU 2082 过路费(树链剖分)

    FZU 2082 过路费 题目链接 树链抛分改动边的模板题 代码: #include <cstdio> #include <cstring> #include <vect ...

  3. FZU Problem 2082 过路费 树链剖分

    Problem 2082 过路费    Problem Description 有n座城市,由n-1条路相连通,使得任意两座城市之间可达.每条路有过路费,要交过路费才能通过.每条路的过路费经常会更新, ...

  4. BZOJ 1036 [ZJOI2008]树的统计Count (树链剖分 - 点权剖分 - 单点权修改)

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1036 树链剖分模版题,打的时候注意点就行.做这题的时候,真的傻了,单词拼错检查了一个多小时 ...

  5. 计蒜客 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 ...

  6. POJ3237 Tree 树链剖分 边权

    POJ3237 Tree 树链剖分 边权 传送门:http://poj.org/problem?id=3237 题意: n个点的,n-1条边 修改单边边权 将a->b的边权取反 查询a-> ...

  7. POJ2763 Housewife Wind 树链剖分 边权

    POJ2763 Housewife Wind 树链剖分 边权 传送门:http://poj.org/problem?id=2763 题意: n个点的,n-1条边,有边权 修改单边边权 询问 输出 当前 ...

  8. HDU3669 Aragorn's Story 树链剖分 点权

    HDU3669 Aragorn's Story 树链剖分 点权 传送门:http://acm.hdu.edu.cn/showproblem.php?pid=3966 题意: n个点的,m条边,每个点都 ...

  9. BZOJ 1984: 月下“毛景树” [树链剖分 边权]

    1984: 月下“毛景树” Time Limit: 20 Sec  Memory Limit: 64 MBSubmit: 1728  Solved: 531[Submit][Status][Discu ...

  10. SPOJ 375 (树链剖分 - 边权剖分 - 修改单边权)

    题目链接:http://acm.hust.edu.cn/vjudge/contest/view.action?cid=28982#problem/I 给你一棵有边权的树,有两个操作:一个操作是输出l到 ...

随机推荐

  1. 解决ubuntu获取root账号并开通ssh

    1.设置root密码 sudo passwd root 2.修改etc/ssh/sshd_config文件 su - root vi /etc/ssh/sshd_config LoginGraceTi ...

  2. [Usaco2008 Mar]River Crossing渡河问题

    题目描述 Farmer John以及他的N(1 <= N <= 2,500)头奶牛打算过一条河,但他们所有的渡河工具,仅仅是一个木筏. 由于奶牛不会划船,在整个渡河过程中,FJ必须始终在木 ...

  3. 深圳某小公司面试题:AQS是什么?公平锁和非公平锁?ReentrantLock?

    AQS总体来说没有想象中那么难,只要了解它的实现框架,那理解起来就不是什么问题了. AQS在Java还是占很重要的地位的,面试也是经常会问. 目前已经连载11篇啦!进度是一周更新两篇,欢迎持续关注 [ ...

  4. ADB 基本命令

    ADB很强大,记住一些ADB命令有助于提高工作效率. 获取序列号: adb get-serialno 查看连接计算机的设备: adb devices 重启机器: adb reboot 重启到bootl ...

  5. MySQL之谓词下推

    MySQL之谓词下推 什么是谓词 在SQL中,谓词就是返回boolean值即true或者false的函数,或是隐式转换为boolean的函数.SQL中的谓词主要有 LKIE.BETWEEN.IS NU ...

  6. (006)每日SQL学习:关于to_char函数

    to_char函数的官方文档说明: 详细to_char请移步:https://www.cnblogs.com/reborter/archive/2008/11/28/1343195.html 需求:n ...

  7. BFS DFS与回溯

    https://blog.csdn.net/u014303647/article/details/88328526 cyc: https://github.com/CyC2018/CS-Notes/b ...

  8. SpringMVC听课笔记(十三:使用拦截器)

    1.定义一个拦截器: 实现 HandlerInterceptor接口 2. 配置 3.运行流程 4.也可以通过<mvc:mapping>给拦截器设定特定的拦截路径,或者<mvc:ex ...

  9. Linux-处理用户输入

    Linux-处理用户输入 1.命令行参数 1.2读取参数 1.3 读取脚本名 1.4测试参数 2.特殊参数变量 2.1 参数统计 2.2抓取所有的数据 3.移动变量 4.处理选项 5.选项标准化 6. ...

  10. Linux-CentOS7环境MySQL安装配置

    Linux-CentOS7环境MySQL安装配置 1. 安装准备 (1)检查MySQL是否已安装 (2)如果有的话,就全部卸载 2. 安装libaio (1)检索相关信息: (2)安装依赖包: 3. ...