题目传送门

操作就是询问某个点的值, 然后就是对一条路径上的值全部修改。

最基本的树刨题目了。

树刨的思想:

1. 对于每个点找到他的重儿子。

void dfs1(int o, int u){sz[u] = 1;for(int i = head[u]; ~i; i = nt[i]){int v = to[i];if(v == o) continue;dfs1(u, v);if(sz[v] > sz[son[u]]) son[u] = v;sz[u] += sz[v];}
}

View Code

2.求DFS序。对于每个节点记录下dfs序,他的父节点,他的祖先节点(也就是这条重链上最高的节点),这个点对应线段树的位置,线段树对应到节点的位置。

在DFS的过程中,先搜重儿子,然后再搜轻儿子,这样可以保证一条重链在线段树中是连续的,故可以用线段树区间修改。

void dfs2(int o, int u, int t){deep[u] = deep[o] + 1;top[u] = t;fa[u] = o;dfn[u] = ++dtot;dto[dtot] = u;if(son[u]) dfs2(u, son[u], t);for(int i = head[u]; ~i; i = nt[i]){int v = to[i];if(v == o || v == son[u]) continue;dfs2(u, v, v);}
}

View Code

3. 接下来就是对路径的修改。

假如我们需要修改 u -- v 这条路径。

那么我们先令fu = top[u],  fv = top[v],  如果不相等,则将深度大的往上跳,跳的时候完成你要的操作。

 相等之后就说明在一条链上了, 这个时候完成操作后就可以退出了。

 注意的是, 判断的是 fu 和 fv 的深度 而不是 u v 的深度。 

void Updata_Path(int x, int y, int c){int fx = top[x], fy = top[y];while(fx != fy){if(deep[fx] > deep[fy]){Updata(dfn[fx],dfn[x],c,1,n,1);x = fa[fx]; fx = top[x];}else {Updata(dfn[fy],dfn[y],c,1,n,1);y = fa[fy]; fy = top[y];}}if(deep[x] < deep[y]) Updata(dfn[x], dfn[y], c, 1, n, 1);else Updata(dfn[y], dfn[x], c, 1, n,1);
}

View Code

代码:

/*
code by: zstu wxk
time: 2019/02/22
*/
#include<bits/stdc++.h>
using namespace std;
#define Fopen freopen("_in.txt","r",stdin); freopen("_out.txt","w",stdout);
#define LL long long
#define ULL unsigned LL
#define fi first
#define se second
#define pb push_back
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define lch(x) tr[x].son[0]
#define rch(x) tr[x].son[1]
#define max3(a,b,c) max(a,max(b,c))
#define min3(a,b,c) min(a,min(b,c))
typedef pair<int,int> pll;
const int inf = 0x3f3f3f3f;
const int _inf = 0xc0c0c0c0;
const LL INF = 0x3f3f3f3f3f3f3f3f;
const LL _INF = 0xc0c0c0c0c0c0c0c0;
const LL mod =  (int)1e9+7;
const int N = 2e5 + 100;
int n, m, p;
int tr[N<<2], lz[N<<2], a[N];
int head[N], nt[N], to[N], tot;
int sz[N], son[N];
int top[N], fa[N], dfn[N], dto[N], deep[N], dtot;
void Build(int l, int r, int rt){lz[rt] = tr[rt] = 0;if(l == r){tr[rt] = a[dto[l]];return ;}int m = l+r >> 1;Build(lson); Build(rson);return ;
}
void PushDown(int rt){if(lz[rt]){lz[rt<<1] += lz[rt];lz[rt<<1|1] += lz[rt];tr[rt<<1] += lz[rt];tr[rt<<1|1] += lz[rt];lz[rt] = 0;}return ;
}
void add(int u, int v){to[tot] = v;nt[tot] = head[u];head[u] = tot++;
}
void dfs1(int o, int u){sz[u] = 1;for(int i = head[u]; ~i; i = nt[i]){int v = to[i];if(v == o) continue;dfs1(u, v);if(sz[v] > sz[son[u]]) son[u] = v;sz[u] += sz[v];}
}
void dfs2(int o, int u, int t){deep[u] = deep[o] + 1;top[u] = t;fa[u] = o;dfn[u] = ++dtot;dto[dtot] = u;if(son[u]) dfs2(u, son[u], t);for(int i = head[u]; ~i; i = nt[i]){int v = to[i];if(v == o || v == son[u]) continue;dfs2(u, v, v);}
}
int Query(int x, int l, int r, int rt){if(l == r)return tr[rt];int m = l+r >> 1;PushDown(rt);if(x <= m) return Query(x, lson);return Query(x, rson);
}
void Updata(int L, int R, int C, int l, int r, int rt){
//    cout << L << " l with r " << r <<  endl;if(L <= l && r <= R){lz[rt] += C;tr[rt] += C;return ;}int m = l+r >> 1;PushDown(rt);if(L <= m) Updata(L, R, C, lson);if(m < R) Updata(L, R, C, rson);return ;
}
void Updata_Path(int x, int y, int c){int fx = top[x], fy = top[y];while(fx != fy){if(deep[fx] > deep[fy]){Updata(dfn[fx],dfn[x],c,1,n,1);x = fa[fx]; fx = top[x];}else {Updata(dfn[fy],dfn[y],c,1,n,1);y = fa[fy]; fy = top[y];}}if(deep[x] < deep[y]) Updata(dfn[x], dfn[y], c, 1, n, 1);else Updata(dfn[y], dfn[x], c, 1, n,1);
}
void init(){memset(head, -1, sizeof(head));memset(son, 0, sizeof son);tot = dtot = 0;
}
void Ac(){for(int i = 1; i <= n; ++i) scanf("%d", &a[i]);for(int i = 1,u,v; i < n; ++i){scanf("%d%d", &u, &v);add(u, v); add(v, u);}dfs1(1,1);dfs2(1,1,1);Build(1,n,1);char op[5];int x, y, c;for(int i = 1; i <= p; ++i){scanf("%s", op);if(op[0] == 'Q') {scanf("%d", &x);printf("%d\n", Query(dfn[x], 1, n, 1));}else {scanf("%d%d%d", &x, &y, &c);if(op[0] == 'D') c = -c;Updata_Path(x,y,c);
//            Tdfs(1,n,1);
         }}
}
int main(){while(~scanf("%d%d%d", &n, &m, &p)){init();Ac();}return 0;
}
/*
3 2 5
1 2 3
2 1
1 3
I 2 3 5
Q 27 6 10
0 0 0 0 0 0 0
1 2
2 3
3 4
1 5
5 6
I 4 6 1
Q 1*/

View Code

转载于:https://www.cnblogs.com/MingSD/p/10418191.html

HDU - 3966 树链刨分相关推荐

  1. 树链刨分 HDU 3966

    树 n个点 m条边(其实就是n-1) q个询问 a1 a2 a3 ... 这些节点开始的人 I  a b c   a->b  这条链上的都加c D    ...                  ...

  2. hdu 3966(树链剖分+线段树区间更新)

    传送门:Problem 3966 https://www.cnblogs.com/violet-acmer/p/9711441.html 学习资料: [1]线段树区间更新:https://blog.c ...

  3. hdu 3966( 树链剖分+点权更新)

    题意:给一棵树,并给定各个点权的值,然后有3种操作: I C1 C2 K: 把C1与C2的路径上的所有点权值加上K D C1 C2 K:把C1与C2的路径上的所有点权值减去K Q C:查询节点编号为C ...

  4. HDU 3966 树链剖分后线段树维护

    题意: 一棵树, 操作1.$path(a,b)$之间的点权$+k$ 操作2.单点查询 题解: 树链剖分即可,注意代码细节,双向映射 主要是记录一下板子 #include <string.h> ...

  5. Game HDU - 5242 树链思想

    GameHDU - 5242 题目大意:一个游戏有n个场景形成了棵有根树,根节点是1,每个场景都有它的权值.然后一个人可以选择其中K个分支来走,而每个场景的权重只算一遍,问最大的权值和. 一开始想叉了 ...

  6. hdu 5274(树链剖分)

    解题思路:这道题据说是树链剖分,所以也学习了一下. http://blog.sina.com.cn/s/blog_7a1746820100wp67.html 不同的是这里是点权值,我按照相似的处理方式 ...

  7. HDU 5405 (树链剖分+线段树)

    Problem Sometimes Naive 题目大意 给你一棵n个节点的树,有点权. 要求支持两种操作: 操作1:更改某个节点的权值. 操作2:给定u,v, 求 Σw[i][j]   i , j ...

  8. hdu 5052 树链剖分+线段树+区间合并

    各种裸,但合在一起好恶心... 因为路径是有向的,所以要维护区间里向两个方向走的最大收益和区间里的最大最小值,要用到区间合并的线段树 #include <iostream> #includ ...

  9. HDU 3966 Aragorn's Story (树链点权剖分,成段修改单点查询)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3966 树链剖分的模版,成段更新单点查询.熟悉线段树的成段更新的话就小case啦. 1 //树链剖分 边 ...

  10. HDU - 3966 Aragorn's Story(树链剖分)

    题目传送门:HDU - 3966 Aragorn's Story 题目大意: 存在一个树,树上每个节点为一个阵营,阵营中存在敌人,现在要进行以下操作 I  C1  C2  K :将阵营C1到阵营C2路 ...

最新文章

  1. Boost--Graph
  2. 【机器学习PAI实践十二】机器学习算法基于信用卡消费记录做信用评分
  3. 使用Qt的多线程编程
  4. 关于ssl免费证书设置
  5. ORA-00600 [4194] 故障处理
  6. [转] 计算机视觉领域稍微容易中的期刊
  7. win10电脑中病毒了怎么办,如何解决电脑中病毒
  8. 一般柱子与柱子的距离_建筑中柱子之间的距离多少为好?
  9. MATLAB 线性运算之图像相加去噪
  10. 前端Swiper滑动的时候最右一个反弹回去了
  11. ASP.NET HttpHandler加水印
  12. 甲骨文每季安全更新再修补297个漏洞
  13. ps裁剪和裁切的区别_PS裁剪和裁切的区别
  14. Java常用工具类-发短信(集成华软通信短信网关)
  15. IR PC IP 之义
  16. 转-STAF学习使用总结一
  17. ToC战场进入尾声,ToB市场战争厮杀即将升级?
  18. 洛谷 P1462 通往奥格瑞玛的道路
  19. Thread--线程创建的三种方式
  20. 中国少儿模特明星盛典 《荣耀王者》主题曲 即将全网发布

热门文章

  1. 如何从PayPal提现
  2. 小葵花妈妈课堂之nginx必须要了解的优化九部曲!
  3. 计算机运行慢提速小技巧,教你为Win7系统加速的五个技巧
  4. 指纹识别技术的发展前景是怎样的?
  5. 交叉熵损失函数权重计算
  6. android 10.0 Camera2 去掉后置摄像头 仅支持前置摄像头功能
  7. Windows10 如何禁用或删除大的Hiberfil.sys和Pagefile.sys文件
  8. 文件上传功能怎么测试
  9. easyui获取图片路径_Easyui filebox(文件框)_EasyUI 插件
  10. pci-e服务器显卡性能,旗舰显卡不同PCI-E模式下性能对比测试