差不多是模板题,不过要注意将边权转化为点权,将边的权值赋给它所连的深度较大的点。

这样操作过后,注意查询ask()的代码有所改变(见代码注释)

  1 #include<cstdio>
2 #include<cstring>
3 #include<algorithm>
4 using namespace std;
5 const int maxn=100010;
6 int head[maxn],to[maxn<<1],nxt[maxn<<1],tot,cnt;
7 int fa[maxn],dep[maxn];
8 int size[maxn],son[maxn],top[maxn];
9 int id[maxn],rev[maxn];
10 int Sum;
11
12 struct edge{
13 int u,v,w;
14 }a[maxn];
15
16 struct node{
17 int l,r,sum;
18 }tree[maxn<<2];
19
20 void add(int u,int v){
21 nxt[++tot]=head[u];
22 head[u]=tot;
23 to[tot]=v;
24 }
25
26 void init(){
27 tot=cnt=0;
28 memset(head,0,sizeof(head));
29 memset(son,0,sizeof(son));
30 }
31
32 void dfs1(int u,int f){
33 size[u]=1,fa[u]=f,dep[u]=dep[f]+1;
34 for(int i=head[u];i;i=nxt[i]){
35 int v=to[i];
36 if(v==f) continue;
37 dfs1(v,u);
38 size[u]+=size[v];
39 if(size[v]>size[son[u]]) son[u]=v;
40 }
41 }
42
43 void dfs2(int u,int t){
44 top[u]=t;
45 id[u]=++cnt;
46 rev[cnt]=u;
47 if(!son[u]) return ;
48 dfs2(son[u],t);
49 for(int i=head[u];i;i=nxt[i]){
50 int v=to[i];
51 if(v!=fa[u] && v!=son[u]) dfs2(v,v);
52 }
53 }
54
55 void pushup(int k){
56 tree[k].sum=tree[k<<1].sum+tree[k<<1|1].sum;
57 }
58
59 void build(int k,int l,int r){
60 tree[k].l=l;tree[k].r=r;
61 if(l==r) return ;
62 int mid=(l+r)>>1;
63 build(k<<1,l,mid);
64 build(k<<1|1,mid+1,r);
65 }
66
67 void change(int k,int x,int y){
68 if(tree[k].l==tree[k].r && tree[k].l==x){
69 tree[k].sum=y;
70 return ;
71 }
72 int mid=(tree[k].l+tree[k].r)>>1;
73 if(x<=mid) change(k<<1,x,y);
74 else change(k<<1|1,x,y);
75 pushup(k);
76 }
77
78 void query(int k,int l,int r){//查询线段树中[l,r]的和值
79 if(tree[k].l>=l && tree[k].r<=r){//找到该区间
80 Sum+=tree[k].sum;
81 return;
82 }
83 int mid=(tree[k].l+tree[k].r)>>1;
84 if(l<=mid) query(k<<1,l,r);
85 if(r>mid) query(k<<1|1,l,r);
86 }
87
88 void ask(int u,int v){
89 while(top[u]!=top[v]){
90 if(dep[top[u]]<dep[top[v]]) swap(u,v);
91 query(1,id[top[u]],id[u]);//这里是top,下面是son,可以画图模拟一下,验证其正确性
92 u=fa[top[u]];
93 }
94 if(u==v) return ;//边权化为点权,加上这一步很有必要,防止重复算
95 if(dep[u]>dep[v]) swap(u,v);
96 query(1,id[son[u]],id[v]);//注意是son[u]
97 }
98
99 int main(){
100 int n,q,s;
101 init();
102 scanf("%d%d%d",&n,&q,&s);
103 for(int i=1;i<n;i++){
104 scanf("%d%d%d",&a[i].u,&a[i].v,&a[i].w);
105 add(a[i].u,a[i].v); add(a[i].v,a[i].u);
106 }
107 dfs1(1,0);
108 dfs2(1,1);
109 build(1,1,cnt);//创建线段树
110 for(int i=1;i<n;i++){//边权转化为点权
111 if(dep[a[i].u]>dep[a[i].v])
112 swap(a[i].u,a[i].v);
113 change(1,id[a[i].v],a[i].w);
114 }
115 int opt,i,val,x;
116 while(q--){
117 scanf("%d",&opt);
118 if(opt){
119 scanf("%d%d",&i,&val);
120 change(1,id[a[i].v],val);//改变第i条边的值为val
121 }
122 else{
123 scanf("%d",&x);
124 Sum=0;
125 ask(s,x);//查询s->x路径上边权的和值
126 printf("%d\n",Sum);
127 s=x;//更新温迪的位置
128 }
129 }
130 return 0;
131 }

最新文章

  1. Django 权限管理
  2. LoadRunner脚本参数化设置
  3. CoreSeek
  4. 关于HTML5在动画制作工具Animatron的一些问题
  5. 配置Nginx支持ThinkPHP的URL重写和PATHINFO
  6. atitit.查看预编译sql问号 本质and原理and查看原生sql语句
  7. OPENSSL编程入门学习
  8. [转]jquery.timer用法
  9. Java程序执行Linux命令
  10. Mysql监控及优化
  11. 4.2 PCIe体系结构的组成部件
  12. SqlServer查询表名的备注(查询表名描述 MS_Description)
  13. gitlab 之 cicd
  14. JavaScript—Date对象详情
  15. 关于PHP中会话技术的知识点分享
  16. CloudStack学习-1
  17. [ERROR] Failed to execute goal org.codehaus.mojo:gwt-maven-plugin:2.5.0-rc1:compile (default) on project zeus-web: Command 解决
  18. Win2012&amp;Win2008双系统启动菜单设置
  19. 多线程---ReentrantLock
  20. CSSREM

热门文章

  1. C# 委托/事件本质详解
  2. nginx反向代理缓存配置
  3. 珠联壁合地设天造|M1 Mac os(Apple Silicon)基于vscode(arm64)配置搭建Java开发环境(集成web框架Springboot)
  4. 企业级数据治理工作怎么开展?Datahub这样做
  5. Odoo14 防暴力破解登录密码
  6. SDK和API的直接区别
  7. SAM复杂度证明
  8. 汇编语言基于8086CUP(想学操作系统的前奏!!!)
  9. MySQL查询性能优化七种武器之索引潜水
  10. LuoguP1283 平板涂色(状压DP)