边权操作起来也和点权一样,只要把边的权值映射到点上即可,要注意的地方是向上爬的过程中和点权不太一样,还有个特判(WA了几次。。)

完整代码

#include<cstring>
#include<cstdio>
#include<iostream>
using namespace std;
#define maxn 100005
struct E{int x,y;}e[maxn];
struct Edge{int to,nxt,w;}edge[maxn<<];
int head[maxn],tot,v[maxn],n,q,c;
void init(){memset(head,-,sizeof head);tot=;}
void addedge(int u,int v,int w){
edge[tot].to=v;edge[tot].w=w;edge[tot].nxt=head[u];head[u]=tot++;
}
int f[maxn],son[maxn],d[maxn],size[maxn];
void dfs1(int x,int pre,int deep){
size[x]=,d[x]=deep,f[x]=pre;
for(int i=head[x];i!=-;i=edge[i].nxt){
int y=edge[i].to;
if(y==pre)continue;
v[y]=edge[i].w;//注意这里将边权映射到点上
dfs1(y,x,deep+);
size[x]+=size[y];
if(size[y]>size[son[x]])son[x]=y;
}
}
int cnt,top[maxn],id[maxn],rk[maxn];
void dfs2(int x,int tp){
top[x]=tp;id[x]=++cnt;rk[cnt]=x;
if(son[x])dfs2(son[x],tp);
for(int i=head[x];i!=-;i=edge[i].nxt){
int y=edge[i].to;
if(y!=f[x] && y!=son[x])dfs2(y,y);
}
} #define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
int sum[maxn<<];
void pushup(int rt){sum[rt]=sum[rt<<]+sum[rt<<|];}
void build(int l,int r,int rt){
if(l==r){sum[rt]=v[rk[l]];return;}
int m=l+r>>;
build(lson);build(rson);
pushup(rt);
}
void update(int pos,int l,int r,int rt,int v){
if(l==r){sum[rt]=v;return;}
int m=l+r>>;
if(pos<=m)update(pos,lson,v);
else update(pos,rson,v);
pushup(rt);
}
int query(int L,int R,int l,int r,int rt){
if(L<=l && R>=r)return sum[rt];
int m=l+r>>,res=;
if(L<=m)res+=query(L,R,lson);
if(R>m)res+=query(L,R,rson);
return res;
} int Query(int x,int y){
int res=;
while(top[x]!=top[y]){
if(d[top[x]]<d[top[y]])swap(x,y);
res+=query(id[top[x]],id[x],,n,);
x=f[top[x]];
}
if(x==y)return res;
if(id[x]>id[y])swap(x,y);
return res+query(id[son[x]],id[y],,n,);
} int main(){
init();int s;
scanf("%d%d%d",&n,&q,&s);
for(int i=;i<n;i++){
int x,y,z;scanf("%d%d%d",&x,&y,&z);
e[i].x=x;e[i].y=y;
addedge(x,y,z);addedge(y,x,z);
}
cnt=;dfs1(s,,);dfs2(s,s);
build(,n,);
while(q--){
int op,x,y;
scanf("%d",&op);
if(op==){scanf("%d",&x);
cout<<Query(s,x)<<'\n';s=x;}
if(op==){
scanf("%d%d",&x,&y);
int u=e[x].x,v=e[x].y;
if(d[u]<d[v])swap(u,v);
update(id[u],,n,,y);
}
}
}

不同之处:最后一次查询的时候不要最高的那个点权

特判:x==y的时候直接返回即可

int Query(int x,int y){
int res=;
while(top[x]!=top[y]){
if(d[top[x]]<d[top[y]])swap(x,y);
res+=query(id[top[x]],id[x],,n,);
x=f[top[x]];
}
if(x==y)return res;
if(id[x]>id[y])swap(x,y);
return res+query(id[son[x]],id[y],,n,);
}

树链剖分——边权poj2763的更多相关文章

  1. POJ2763 Housewife Wind 树链剖分 边权

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

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

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

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

  4. POJ3237 Tree 树链剖分 边权

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

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

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

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

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

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

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

  8. 树链剖分边权模板spoj375

    树链剖分是树分解成多条链来解决树上两点之间的路径上的问题 如何求出树链:第一次dfs求出树上每个结点的大小和深度和最大的儿子,第二次dfs就能将最大的儿子串起来并hash(映射)到线段树上(或者其他数 ...

  9. 洛谷 P3384 【模板】树链剖分-树链剖分(点权)(路径节点更新、路径求和、子树节点更新、子树求和)模板-备注结合一下以前写的题目,懒得写很详细的注释

    P3384 [模板]树链剖分 题目描述 如题,已知一棵包含N个结点的树(连通且无环),每个节点上包含一个数值,需要支持以下操作: 操作1: 格式: 1 x y z 表示将树从x到y结点最短路径上所有节 ...

随机推荐

  1. cocos 碰撞系统

    前面的话 本文将简要介绍 Cocos Creator 中的碰撞系统,Cocos Creator 内置了一个简单易用的碰撞检测系统,支持圆形.矩形以及多边形相互间的碰撞检测 编辑碰撞组件 当添加了一个碰 ...

  2. python3 while-else和for-else语法

    while-else: while判断条件不成立时,执行else语句: 语法: while 判断条件: 语句1.... else: 语句2.... i初始值为2,i>0成立,则执行while语句 ...

  3. promise和setTimeout执行顺序的问题

    提出问题,问题代码为 setTimeout(function(){console.log(1)},0); new Promise(function(resolve){ console.log(2) f ...

  4. mysql 数据库表迁移复制

    1. 表结构相同的表,且在同一数据库(如,table1,table2) insert into table1 select * from table2 # 完全复制 insert into table ...

  5. plink计算两个SNP位点的连锁不平衡值(LD)

    PLINK提供了“--ld”的参数计算两个SNP位点的连锁不平衡值. 命令如下: plink --file file --ld rs123 rs134 --out rs123_rs134 生成如下数据 ...

  6. codeforces-1132 (div2)

    A.发现b的个数没有意义,a不等于d一定不可行,c不管多少都算一个,如果只有c没有ad也不可行 #include <map> #include <set> #include & ...

  7. Rancher2.1安装部署

    基础环境配置 1.操作系统选择 Ubuntu 16.04(64位 Server版) Centos/RedHat Linux 7.5+(64位) 2.Docker版本选择 1.12.6 1.13.1 1 ...

  8. Hbase 客户端Scan

    Hbase 客户端Scan 标签(空格分隔): Hbase HBase扫描操作Scan 1 介绍 扫描操作的使用和get()方法类似.同样,和其他函数类似,这里也提供了Scan类.但是由于扫描工作方式 ...

  9. .net core引用错误的Entity Framework而导致不能正常迁移数据的解决办法

    本人刚学.net core,因此在学习过程中会遇上许许多多的坑.每一位初学者最大的问题在于资料的查看不仔细或是没有正确理解里面的内容,导致在后面自己在不知道错误的情况下做了一个小动作.对于完全没有理解 ...

  10. mysql-binlog日志删除

    第一种方法: mysql> show binary logs; 查看mysql bin-log日志,除了这个以外的,其它都可以使用删除. mysql> purge binary logs ...