Hdu--3966(树链剖分,线段树 or 树状数组)

2014-10-05 16:30:43

思路:权在点上的线段树,加上树链剖分即可。注意这题容易RE爆栈,要手动扩栈!

  1 /*************************************************************************
  2     > File Name: 3966.cpp
  3     > Author: Nature
  4     > Mail: 564374850@qq.com 
  5     > Created Time: Sun 05 Oct 2014 01:20:20 PM CST
  6 ************************************************************************/
  7 #pragma comment(linker,"/STACK:1024000000,1024000000")
  8 #include <cstdio>
  9 #include <cstring>
 10 #include <cstdlib>
 11 #include <iostream>
 12 #include <algorithm>
 13 using namespace std;
 14 #define lp (p << 1)
 15 #define rp (p << 1|1)
 16 #define getmid(l,r) (l + (r - l) / 2)
 17 const int maxn = 50010;
 18 
 19 int N,M,P;
 20 int A[maxn];
 21 int first[maxn],next[maxn << 1],ver[maxn << 1],ecnt;
 22 int dep[maxn],sz[maxn],son[maxn],fa[maxn],top[maxn],w[maxn],aw[maxn],tsz;
 23 
 24 struct node{
 25     int add;
 26     int val;
 27 }t[maxn << 2];
 28 
 29 void Add_edge(int u,int v){
 30     next[++ecnt] = first[u];
 31     ver[ecnt] = v;
 32     first[u] = ecnt;
 33 }
 34 
 35 void Dfs(int p,int pre,int d){
 36     sz[p] = 1;
 37     dep[p] = d;
 38     fa[p] = pre;
 39     son[p] = -1;
 40     int v,tmp = 0;
 41     for(int i = first[p]; i != -1; i = next[i]) if((v = ver[i]) != pre){
 42         Dfs(v,p,d + 1);
 43         if(sz[v] > tmp){
 44             son[p] = v;
 45             tmp = sz[v];
 46         }
 47         sz[p] += sz[v];
 48     }
 49 }
 50 
 51 void Dfs_pos(int p,int tp){
 52     w[p] = ++tsz;
 53     aw[tsz] = p;
 54     top[p] = tp;
 55     if(son[p] != -1) Dfs_pos(son[p],tp);
 56     for(int i = first[p]; i != -1; i = next[i]){
 57         int v = ver[i];
 58         if(v != son[p] && v != fa[p])
 59             Dfs_pos(v,v);
 60     }
 61 }
 62 
 63 void Build_tree(int p,int l,int r){
 64     t[p].add = 0;
 65     if(l == r){
 66         t[p].val = A[aw[l]];
 67         return;
 68     }
 69     int mid = getmid(l,r);
 70     Build_tree(lp,l,mid);
 71     Build_tree(rp,mid + 1,r);
 72 }
 73 
 74 void Update_tree(int a,int b,int c,int p,int l,int r){
 75     if(a <= l && r <= b){
 76         t[p].add += c;
 77         return;
 78     }
 79     int mid = getmid(l,r);
 80     if(a <= mid) Update_tree(a,b,c,lp,l,mid);
 81     if(b > mid) Update_tree(a,b,c,rp,mid + 1,r);
 82 }
 83 
 84 int Query_tree(int a,int p,int l,int r,int plu){
 85     if(l == r)
 86         return t[p].val + t[p].add + plu;
 87     int mid = getmid(l,r);
 88     if(a <= mid) return Query_tree(a,lp,l,mid,plu + t[p].add);
 89     else return Query_tree(a,rp,mid + 1,r,plu + t[p].add);
 90 }
 91 
 92 void Change(int a,int b,int c){
 93     int f1 = top[a],f2 = top[b];
 94     while(f1 != f2){
 95         if(dep[f1] > dep[f2]){
 96             swap(a,b);
 97             swap(f1,f2);
 98         }
 99         Update_tree(w[f2],w[b],c,1,1,tsz);
100         b = fa[f2];
101         f2 = top[b];
102     }
103     if(dep[a] > dep[b]) swap(a,b);
104     Update_tree(w[a],w[b],c,1,1,tsz);
105 }
106 
107 void Init(){
108     memset(first,-1,sizeof(first));
109     ecnt = 0;
110     tsz = 0;
111 }
112 
113 int main(){
114     char s[5];
115     int a,b,c;
116     while(scanf("%d%d%d",&N,&M,&P) != EOF){
117         Init();
118         for(int i = 1; i <= N; ++i)
119             scanf("%d",A + i);
120         for(int i = 1; i < N; ++i){
121             scanf("%d%d",&a,&b);
122             Add_edge(a,b);
123             Add_edge(b,a);
124         }
125         Dfs(1,0,0);
126         Dfs_pos(1,1);
127         Build_tree(1,1,tsz);
128         for(int i = 1; i <= P; ++i){
129             scanf("%s%d",s,&a);
130             if(s[0] == 'I' || s[0] == 'D'){
131                 scanf("%d%d",&b,&c);
132                 if(s[0] == 'D') Change(a,b,-c);
133                 else Change(a,b,c);
134             }
135             else printf("%d\n",Query_tree(w[a],1,1,tsz,0));
136         }
137     }
138     return 0;
139 }

 

转载于:https://www.cnblogs.com/naturepengchen/articles/4007125.html

2023华为od机试C卷【最富裕的小家庭】C语言 实现 在一颗树中,每个节点代表一个家庭成员,节点的数字表示其个人的财富值,一个节点及其直接相连的子节点被定义为个小家庭。现给你一颗树,请计算出最富裕的小家庭的财富和。 阅读详情

相关推荐

OpenStack 2018 年终盘点

目录 文章目录目录前言OpenStack 一年来的成长NovaCinderNeutronIronicCyborgOctaviaKollaMagnumZunKuryr从 OpenStack 到 OpenInfra 前言 这是最好的时代,也是最坏的时代 — — 查尔斯·约翰·赫芬姆·狄更斯《双城记》 年关将至,闲暇之余,回顾我与 OpenStack 的 2018。 NOTE:仅作为个人见解,与公...

烟云的计算 3551

hdu 3966 Aragorn's Story(树链剖分+树状数组)

题目链接:hdu 3966 Aragorn's Story 题目大意:给定一个棵树,然后三种操作 Q x:查询节点x的值I x y w:节点x到y这条路径上所有节点的值增加wD x y w:节点x到y这条路径上所有节点的值减少w 解题思路:树链剖分,用树状数组维护每个节点的值。 #pragma comment(linker, "/STACK:1024000000,1024000

不慌不忙、不急不躁 1304

Far planner 代码系列(33) 关于real_world_contour和contour_graph

我们知道far planner前部分的流程是这样子的: 对于特定的地图,如下: 我们要从surround_obs_cloud里抽取生成realworld_contour_,如下图所示: 在这时候,每个node的z坐标都是以机器人的高度定的。如图所示: 先去吃饭啦~待会回来在写 ...

博客 731

hdu--3966(树链剖分)

题目链接:hdu--3966 给出n个点的值,还有n-1条边的连接方式,三种操作: 1、I在节点a到b的路径中所有的点都增加x 2、D在节点a到b的路径中所有的点都减少x 3、Q询问第k个节点的值。 将每个节点的值转化为父节点到子节点的边的权值,对于根节点做一个虚拟的父节点0 。进行树链剖分,整合到线段树中之后注意: 更新时,不能只更新a到b上的边的权值,因为那样会使b节点的权值不能被

随风的专栏 1610

hdu 3966(树链剖分)

题意:有一棵树,上面n个节点,每个节点都有一个权值,有三种操作,I a b c,把从节点a到节点b路径上所有点(包括a和b)权值都加c,D a b c,把从节点a到节点b路径上所有点权值都减c,Q a,问节点a的权值。 题解:树链剖分模板题,线段树维护区间和,用到单点查询,区间更新。#include <cstdio> #include <cstring> #include <algorithm>

俯瞰风景 565

hdu 3966树链剖分树状数组/线段树

题目:http://acm.hdu.edu.cn/showproblem.php?pid=3966 题意: 给一棵树,并给定各个点权的值,然后有3种操作: I C1 C2 K: 把C1与C2的路径上的所有点权值加上K D C1 C2 K:把C1与C2的路径上的所有点权值减去K Q C:查询节点编号为C的权值 分析: 树链剖分入门题,基于点的重编号。 操作是区间增减

HARD_UNDERSTAND 546

HDU 3966树链剖分

传送门 题意: 给你一个有nnn个顶点的树,树上的每一个点都有一个点权,现在有333种操作: I u v kI~ u~v~kI u v k,代表将结点uuu到结点vvv的最近的路径上的所有点的点权增加kkk D u v kD~ u~v~kD u v k ,代表将结点uuu到结点...

Chen.Jr的博客 275

HDU - 3966 Aragorn's Story(树链剖分树状数组模式)

Our protagonist is the handsome human prince Aragorn comes from The Lord of the Rings. One day Aragorn finds a lot of enemies who want to invade his kingdom. As Aragorn knows, the enemy has N camps ou...

柳予欣的三味书屋~ 270

HDU 3966 /// 树链剖分+树状数组

题意: http://acm.hdu.edu.cn/showproblem.php?pid=3966 给一棵树,并给定各个点权的值,然后有3种操作: I x y z :把x到y的路径上的所有点权值加上z Dx y z:把x到y的路径上的所有点权值减去z Qz:查询节点编号为x的权值 这里主要放下用树状数组维护的模板 区间修改单点查询 好像用线段树更好? em....

babimei370256276的博客 140

Hdu 3966 Aragorn's Story 树链剖分+树状数组

Aragorn's Story Time Limit: 10000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 12674    Accepted Submission(s): 3395 Problem Description Our prot

J. Cole 364

HDU3966树链剖分】。

树的拆分: 看了很多资料终于明白一点了,稍微做一下总结。 首先我们应该知道树的拆分分是用来做什么的: 所谓拆分就是把一颗树状结构拆分成线性的结构,然后就可以用树状数组线段树维护路径,把每次更新或者查询的复杂度做操控制在O(NlogN)左右。树的拆分方式貌似有很多种,比如最简单的DFS序, 记录的是每个节点u以及u的所有子树的在内的线性标号,即 区间【b

VecSun的博客 1074

HDU-3966 Aragorn's Story【树链剖分+线段树/树状数组】\【动态树LCT】

题意 在一个NNN个结点的树上,每个节点上都有权值。有PPP次询问。 3种询问: I c1 c2 kI\ c1\ c2\ kI c1 c2 k 表示 从c1节点到c2节点的路径上所有点权值增加k D c1 c2 kD\ c1\ c2\ kD c1 c2 k 表示 从c1节点...

Irimsky 227

HDU3966】Aragorn's Story(树链剖分+线段树)

树链剖分用一句话概括就是:把一棵树剖分为若干条链,然后利用数据结构(树状数组,SBT,Splay,线段树等等)去维护每一条链,复杂度为O(logn)那么,树链剖分的第一步当然是对树进行轻重边的划分。定义size(x)为以x为根的子树节点个数,令v为u的儿子中size值最大的节点,那么(u,v)就是重边,其余边为轻边。当然,关于这个它有两个重要

No Program No Life 591

HDU 3966 Aragorn's Story 树链剖分+树状数组树链剖分+线段树

HDU 3966Aragorn's Story 先把树剖成链,然后用树状数组维护: 讲真,研究了好久,还是没明白 树状数组这样实现"区间更新+单点查询"的原理... 神奇... #include <stdio.h> #include <string.h> #include <iostream> #include <algor...

weixin_30666753的博客 136

HDU 3966 Aragorn's Story [树链剖分(点权)+树状数组]【数据结构】

题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=3966——————————————————————————-. Aragorn’s StoryTime Limit: 10000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submission(s)

Tabris的博客 691

hdu3966Aragorn's Story【树链剖分+树状数组

实在是受不了邝斌那种非得用单点更新的函数写区间更新的写法,太不好理解了,自己在这个基础上改了,mark一下,以后比赛的时候要打印 一个小错误是如果初始值不加入树中,最后求再加进去的时候下标不要换成p[u]!所以说,自己写示例是多么重要 /************ hdu3966 2016.2.2 1014MS 9792K 2876 B G++ ************/ #include #

MissZhou要努力 1024

HDU-3966树链剖分线段树

树链指树上的路径。分重链和轻链

Gikieng的奋斗路 992

HDU - 3966树链剖分

讲解:https://blog.csdn.net/qq_45458915/article/details/102993978 代码: #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; const int N=5e...

weixin_45113721的博客 227

HDU3966(树链剖分)

题目:Aragorn's Story   题意:给一棵树,并给定各个点权的值,然后有3种操作: I C1 C2 K: 把C1与C2的路径上的所有点权值加上K D C1 C2 K:把C1与C2的路径上的所有点权值减去K Q C:查询节点编号为C的权值   分析:典型的树链剖分题目,先进行剖分,然后用线段树去维护即可,注意HDU的OJ采用Windows系统,容易爆栈,所以在代码 前面加

ACdreamer 9381

HDU3966 Aragorn's Story 树链剖分

裸地不能在裸的树链剖分了,col忘记清空,狂wa一小时。 本来想学LINK CUT TREE的,考试接踵,做题状态全无。== ==暂时顺延了 Aragorn's Story Time Limit: 10000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submis

1197

树状数组树链剖分

其实树状数组线段树写树剖都差不多,只是换了一种储存数据的方式,一种占用空间小,但是相对耗时,一种占用空间大,但是很快。 模板题:树链剖分树状数组会 tle 但是这也是一种思路 // Created by CAD on 2019/8/11. #include <bits/stdc++.h> using namespace std; using ll=long lo...

b24384504986189的博客 284

hdu3966(数链剖分+线段树区间更新)

线段树区间更新得通过新映射的区间进行更新。 PS:当初ad数组开小了,wa了好好几次,可惜 #include using namespace std; typedef long long ll; typedef pair P; #define fi first #define se second #define INF 0x3f3f3f3f #define clr(x,y) m

Everything can be done! 601

java网上商城(ssm)

注:原创作品,禁止商业用途,仅供学习参考!资源备案号:18092150 ,盗版必究!!!(希望能帮助有需要的人,如果觉得资源不错的,请给资源打赏个好评)采用的框架(ssm):Spring+SpringMVC+MyBatis使用的数据库:MySQL采用的页面:Jsp ,CSS, JQuery,Ajax等技术内含完整版源码+数据库,Tomcat、jdk1.7+开发工具:MyEclipse,Eclipse,Idea,可直接导入运行功能介绍+系统视频演示地址:https://blog.csdn.net/dengkinsang/article/details/104939197

yt-dlp 2026.07.04 Windows x64 安装包 官方原版

yt-dlp 视频下载工具 2026.07.04 官方原版安装包,Windows x64 平台,支持数百个网站视频解析下载,解压即用。蓝奏云下载链接在加密包内,附完整使用说明。

上一篇: Hdu--5057(树状数组,空间优化,在线 / 离线)
下一篇: Bzoj--1036(树链剖分,线段树)
dingdi3021
博客等级 码龄10年 1粉丝 230原创
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值