HDU5692(线段树+dfs序)

Snacks

Time Limit:5000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u

Submit Status

Description

百度科技园内有n个零食机,零食机之间通过n−1条路相互连通。每个零食机都有一个值v,表示为小度熊提供零食的价值。

由于零食被频繁的消耗和补充,零食机的价值v会时常发生变化。小度熊只能从编号为0的零食机出发,并且每个零食机至多经过一次。另外,小度熊会对某个零食机的零食有所偏爱,要求路线上必须有那个零食机。

为小度熊规划一个路线,使得路线上的价值总和最大。

Input

输入数据第一行是一个整数T(T≤10),表示有T组测试数据。

对于每组数据,包含两个整数n,m(1≤n,m≤100000),表示有n个零食机,m次操作。

接下来n−1行,每行两个整数x和y(0≤x,y<n),表示编号为x的零食机与编号为y的零食机相连。

接下来一行由n个数组成,表示从编号为0到编号为n−1的零食机的初始价值v(|v|<100000)。

接下来m行,有两种操作:0 x y,表示编号为x的零食机的价值变为y;1 x,表示询问从编号为0的零食机出发,必须经过编号为x零食机的路线中,价值总和的最大值。

本题可能栈溢出,辛苦同学们提交语言选择c++,并在代码的第一行加上:

`#pragma comment(linker, "/STACK:1024000000,1024000000") `

Output

对于每组数据,首先输出一行”Case #?:”,在问号处应填入当前数据的组数,组数从1开始计算。

对于每次询问,输出从编号为0的零食机出发,必须经过编号为x零食机的路线中,价值总和的最大值。

Sample Input

1
6 5
0 1
1 2
0 3
3 4
5 3
7 -5 100 20 -5 -7
1 1
1 3
0 2 -1
1 1
1 5

Sample Output

Case #1:
102
27
2
20

线段树+dfs序
  1 //2016.8.11
  2 #pragma comment(linker, "/STACK:1024000000, 1024000000")
  3 #include<iostream>
  4 #include<cstdio>
  5 #include<vector>
  6 #include<algorithm>
  7 #define N 100005
  8 #define lson (id<<1)
  9 #define rson ((id<<1)|1)
 10 #define mid ((l+r)>>1)
 11
 12 using namespace std;
 13
 14 struct node
 15 {
 16     long long max, lazy;
 17 }tree[N*5];
 18
 19 vector<int> v[N];
 20 long long w[N], val[N];//val[i]表示从根节点走到i节点的价值和
 21 int in[N], out[N], flag;//in记录查询区间的左端,out记录查询区间的右端
 22
 23
 24 //线段树模板
 25 //************************************************************************************
 26 void push_up(int id)
 27 {
 28     tree[id].max = max(tree[lson].max, tree[rson].max);
 29     return;
 30 }
 31
 32 void build_tree(int id, int l, int r)
 33 {
 34     if(l == r)
 35     {
 36         tree[id].max = val[l];
 37         tree[id].lazy = 0;
 38         return ;
 39     }
 40     build_tree(lson, l, mid);
 41     build_tree(rson, mid+1, r);
 42     push_up(id);
 43     tree[id].lazy = 0;
 44     return ;
 45 }
 46
 47 void push_down(int id, int l, int r)
 48 {
 49     if(tree[id].lazy)
 50     {
 51         tree[lson].lazy += tree[id].lazy;
 52         tree[rson].lazy += tree[id].lazy;
 53         tree[lson].max += tree[id].lazy;
 54         tree[rson].max += tree[id].lazy;
 55         tree[id].lazy = 0;
 56     }
 57     return ;
 58 }
 59
 60 void ins(int id, int l, int r, int ql, int qr, int tt)
 61 {
 62     if(ql<=l&&r<=qr)
 63     {
 64         tree[id].max += tt;
 65         tree[id].lazy += tt;
 66         return;
 67     }
 68     if(tree[id].lazy) push_down(id, l, r);
 69     if(ql<=mid)
 70           ins(lson, l, mid, ql, qr, tt);
 71     if(mid+1<=qr)
 72           ins(rson, mid+1, r, ql, qr, tt);
 73     push_up(id);
 74     return;
 75 }
 76
 77 long long query(int id, int l, int r, int ql, int qr)
 78 {
 79     if(ql<=l && r<=qr)
 80     {
 81         return tree[id].max;
 82     }
 83     if(tree[id].lazy)
 84           push_down(id, l, r);
 85     long long maxnum = -9999999999999;
 86     if(ql<=mid) maxnum = max(maxnum, query(lson, l, mid, ql, qr));
 87     if(mid+1<=qr) maxnum = max(maxnum, query(rson, mid+1, r, ql, qr));
 88     return maxnum;
 89 }
 90 //************************************************************************************
 91
 92 void dfs(int a, int fa, long long wight)
 93 {
 94     in[a] = ++flag;
 95     for(int i = 0; i < v[a].size(); i++)
 96     {
 97         int b = v[a][i];
 98         if(b==fa)continue;
 99         dfs(b, a, w[b]+wight);
100     }
101     out[a] = flag;
102     val[in[a]] = wight;
103 }
104
105 int main()
106 {
107     int T, n, m, a, b, cmd;
108     cin>>T;
109     for(int kase = 1; kase <= T; kase++)
110     {
111         printf("Case #%d:\n", kase);
112         cin>>n>>m;
113         for(int i = 0; i < N; i++)
114             v[i].clear();
115         for(int i = 0; i < n-1; i++)
116         {
117             scanf("%d%d", &a, &b);
118             a++; b++;
119             v[a].push_back(b);
120             v[b].push_back(a);
121         }
122         for(int i = 1 ; i <= n; i++)
123           scanf("%lld", &w[i]);
124         flag = 0;
125         dfs(1, 0, w[1]);
126         for(int i = 1; i <= n; i++)
127           cout<<in[i]<<" "<<out[i]<<endl;
128         build_tree(1, 1, n);
129         while(m--)
130         {
131             scanf("%d", &cmd);
132             if(cmd == 0)
133             {
134                 scanf("%d%d", &a, &b);a++;
135                 ins(1, 1, n, in[a], out[a], b-w[a]);
136                 w[a] = b;
137             }else
138             {
139                 scanf("%d", &a); a++;
140                 long long ans = query(1, 1, n, in[a], out[a]);
141                 cout<<ans<<endl;
142             }
143         }
144     }
145
146     return 0;
147 }
时间: 2024-10-08 14:21:42

HDU5692(线段树+dfs序)的相关文章

Tsinsen A1505. 树(张闻涛) 倍增LCA,可持久化线段树,DFS序

题目:http://www.tsinsen.com/A1505 A1505. 树(张闻涛) 时间限制:1.0s   内存限制:512.0MB 总提交次数:196   AC次数:65   平均分:58.62 将本题分享到: 查看未格式化的试题   提交   试题讨论 试题来源 2013中国国家集训队第二次作业 问题描述 给定一棵N个节点的树,每个点有一个权值,有M个询问(a,b,c)若a 为1,回答b到c路径上的最小权值,若a为2,回答b到c路径上的最大权值,若a为3,回答b到c路径上的所有权值的

Codeforces 384E 线段树+dfs序

题目链接:点击打开链接 题意: 给定n个点,m个询问的无向树(1为根) 下面n个数表示每个点的权值 下面n-1行给出树 操作1:x点权值+v, x的第 i & 1 的儿子-v, 第 !(i&1) 的儿子+v 操作2:询问x点权值 dfs把树转成序列 根据深度把点分成2组 分别用线段树维护.. 然后Y一下 #include<stdio.h> #include<string.h> #include<iostream> #include<algorith

线段树+dfs序(Apple Tree )(Assign the task )

线段树+dfs序 给定一棵n个节点的树,m次查询,每次查询需要求出某个节点深度为h的所有子节点. 作为预处理,首先将树的所有节点按深度保存起来,每个深度的所有节点用一个线性结构保存,每个深度的节点相对顺序要和前序遍历一致. 然后从树的根节点进行dfs,对于每个节点记录两个信息,一个是dfs进入该节点的时间戳in[id],另一个是dfs离开该节点的时间戳out[id]. 最后对于每次查询,求节点v在深度h的所有子节点,只需将深度为h并且dfs进入时间戳在in[v]和out[v]之间的所有节点都求出

HDU 5692 线段树+dfs序

Snacks Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 1779    Accepted Submission(s): 427 Problem Description 百度科技园内有n 个零食机,零食机之间通过n−1 条路相互连通.每个零食机都有一个值v ,表示为小度熊提供零食的价值. 由于零食被频繁的消耗和补充,零食机的价值v

【BZOJ-3779】重组病毒 LinkCutTree + 线段树 + DFS序

3779: 重组病毒 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 224  Solved: 95[Submit][Status][Discuss] Description 黑客们通过对已有的病毒反编译,将许多不同的病毒重组,并重新编译出了新型的重组病毒.这种病毒的繁殖和变异能力极强.为了阻止这种病毒传播,某安全机构策划了一次实验,来研究这种病毒.实验在一个封闭的局域网内进行.局域网内有n台计算机,编号为1~n.一些计算机之间通过网线直接相连,形

【BZOJ-3306】树 线段树 + DFS序

3306: 树 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 792  Solved: 262[Submit][Status][Discuss] Description 给定一棵大小为 n 的有根点权树,支持以下操作: • 换根 • 修改点权      • 查询子树最小值 Input 第一行两个整数 n, Q ,分别表示树的大小和操作数. 接下来n行,每行两个整数f,v,第i+1行的两个数表示点i的父亲和点i的权.保证f < i.如 果f = 0

【codevs1228】苹果树【线段树+dfs序】

题目描述 Description 在卡卡的房子外面,有一棵苹果树.每年的春天,树上总会结出很多的苹果.卡卡非常喜欢吃苹果,所以他一直都精心的呵护这棵苹果树.我们知道树是有很多分叉点的,苹果会长在枝条的分叉点上面,且不会有两个苹果结在一起.卡卡很想知道一个分叉点所代表的子树上所结的苹果的数目,以便研究苹果树哪些枝条的结果能力比较强. 卡卡所知道的是,每隔一些时间,某些分叉点上会结出一些苹果,但是卡卡所不知道的是,总会有一些调皮的小孩来树上摘走一些苹果. 于是我们定义两种操作: C x 表示编号为x

BZOJ_3252_攻略_线段树+dfs序

Description 题目简述:树版[k取方格数] 众所周知,桂木桂马是攻略之神,开启攻略之神模式后,他可以同时攻略k部游戏.今天他得到了一款新游戏<XX 半岛>,这款游戏有n个场景(scene),某些场景可以通过不同的选择支到达其他场景.所有场景和选择支构成树状 结构:开始游戏时在根节点(共通线),叶子节点为结局.每个场景有一个价值,现在桂马开启攻略之神模式,同 时攻略k次该游戏,问他观赏到的场景的价值和最大是多少(同一场景观看多次是不能重复得到价值的) “为什么你还没玩就知道每个场景的价

K. Random Numbers(Gym 101466K + 线段树 + dfs序 + 快速幂 + 唯一分解)

题目链接:http://codeforces.com/gym/101466/problem/K 题目: 题意: 给你一棵有n个节点的树,根节点始终为0,有两种操作: 1.RAND:查询以u为根节点的子树上的所有节点的权值的乘积x,及x的因数个数. 2.SEED:将节点u的权值乘以x. 思路: 比赛时少看了因数不大于13这句话,然后本题难度增加数倍,肝了两个小时都没肝出来,对不起队友啊,今天的组队训练赛实力背锅…… 这题一眼线段树,由于是对一棵子树进行处理,因此我们采用常规套路,借助dfs序将子树