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

会时常发生变化。小度熊只能从编号为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

Source

2016"百度之星" - 初赛(Astar Round2A)

题意:中文题面

题解:第一次写线段树+dfs序列

  1 /******************************
  2 code by drizzle
  3 blog: www.cnblogs.com/hsd-/
  4 ^ ^    ^ ^
  5  O      O
  6 ******************************/
  7 #include<bits/stdc++.h>
  8 #include<map>
  9 #include<set>
 10 #include<cmath>
 11 #include<queue>
 12 #include<bitset>
 13 #include<math.h>
 14 #include<vector>
 15 #include<string>
 16 #include<stdio.h>
 17 #include<cstring>
 18 #include<iostream>
 19 #include<algorithm>
 20 #pragma comment(linker, "/STACK:102400000,102400000")
 21 using namespace std;
 22 #define  A first
 23 #define B second
 24 const int mod=1000000007;
 25 const int MOD1=1000000007;
 26 const int MOD2=1000000009;
 27 const double EPS=0.00000001;
 28 //typedef long long ll;
 29 typedef __int64 ll;
 30 const ll MOD=1000000007;
 31 const int INF=1000000010;
 32 const ll MAX=1ll<<55;
 33 const double eps=1e-5;
 34 const double inf=~0u>>1;
 35 const double pi=acos(-1.0);
 36 typedef double db;
 37 typedef unsigned int uint;
 38 typedef unsigned long long ull;
 39 int T,n,m,x,judge,nedge=0,dfn, y;
 40 struct node
 41 {
 42     int ed;
 43     int pre;
 44 } N[200005];
 45 int pre[200005],in[200005],out[200005];
 46 ll v[200005];
 47 ll seq[200005];
 48 ll fuck;
 49 struct tree
 50 {
 51     int l,r;
 52     ll lazy;
 53     ll maxn;
 54 } tree[400005];
 55 inline void add(int st,int ed)
 56 {
 57     nedge++;
 58     N[nedge].ed=ed;
 59     N[nedge].pre=pre[st];
 60     pre[st]=nedge;
 61 }
 62 inline void getdfs(int x,int y,ll s)
 63 {
 64     s+=v[x];
 65     in[x]=++dfn;
 66     seq[dfn]=s;
 67     for(int i=pre[x]; i; i=N[i].pre)
 68     {
 69         if(N[i].ed!=y)
 70         {
 71             getdfs(N[i].ed,x,s);
 72         }
 73     }
 74     out[x]=dfn;
 75 }
 76 inline void pushdown(int root)
 77 {
 78     if(tree[root].lazy==0) return;
 79     tree[root<<1].lazy+=tree[root].lazy;
 80     tree[root<<1|1].lazy+=tree[root].lazy;
 81     tree[root<<1].maxn+=tree[root].lazy;
 82     tree[root<<1|1].maxn+=tree[root].lazy;
 83     tree[root].lazy=0;
 84 }
 85 inline void buildtree(int root,int left,int right)
 86 {
 87     tree[root].l=left;
 88     tree[root].r=right;
 89     tree[root].lazy=0;
 90     if(left==right)
 91     {
 92         tree[root].maxn=seq[left];
 93         return ;
 94     }
 95     int mid=(left+right)>>1;
 96     buildtree(root<<1,left,mid);
 97     buildtree(root<<1|1,mid+1,right);
 98     tree[root].maxn=max(tree[root<<1].maxn,tree[root<<1|1].maxn);
 99 }
100 inline void updata(int root,int in,int out,ll after)
101 {
102     if(in==tree[root].l&&tree[root].r==out)
103     {
104         tree[root].lazy+=after;
105         tree[root].maxn+=after;
106         return ;
107     }
108     pushdown(root);
109     int mid=(tree[root].l+tree[root].r)>>1;
110     if(out<=mid)
111         updata(root<<1,in,out,after);
112     else
113     {
114         if(in>mid)
115             updata(root<<1|1,in,out,after);
116         else
117         {
118             updata(root<<1,in,mid,after);
119             updata(root<<1|1,mid+1,out,after);
120         }
121     }
122     tree[root].maxn=max(tree[root<<1].maxn,tree[root<<1|1].maxn);
123 }
124 inline ll query(int root,int in,int out)
125 {
126     if(in==tree[root].l&&tree[root].r==out)
127     {
128         return tree[root].maxn;
129     }
130     pushdown(root);
131     int mid=(tree[root].l+tree[root].r)>>1;
132     if(out<=mid)
133         return query(root<<1,in,out);
134     else
135     {
136         if(in>mid)
137             return query(root<<1|1,in,out);
138         else
139             return max(query(root<<1,in,mid),query(root<<1|1,mid+1,out));
140     }
141 }
142 void init()
143 {
144     memset(tree,0,sizeof(tree));
145     memset(N,0,sizeof(N));
146     memset(pre,0,sizeof(pre));
147     memset(in,0,sizeof(in));
148     memset(out,0,sizeof(out));
149     memset(v,0,sizeof(v));
150     memset(seq,0,sizeof(seq));
151     nedge=0;
152     dfn=0;
153 }
154 int main()
155 {
156         scanf("%d",&T);
157         for(int i=1; i<=T; i++)
158         {
159             init();
160             scanf("%d %d",&n,&m);
161             for(int j=1; j<n; j++)
162             {
163                 scanf("%d %d",&x,&y);
164                 x++;
165                 y++;
166                 add(x,y);
167                 add(y,x);
168             }
169             for(int j=1; j<=n; j++)
170                 scanf("%I64d",&v[j]);
171             getdfs(1,1,0);
172             buildtree(1,1,n);
173             printf("Case #%d:\n",i);
174             for(int j=1; j<=m; j++)
175             {
176                 scanf("%d %d",&judge,&x);
177                 if(judge==0)
178                 {
179                     scanf("%I64d",&fuck);
180                     x++;
181                     ll exm=fuck;
182                     fuck=fuck-v[x];
183                     updata(1,in[x],out[x],fuck);
184                     v[x]=exm;
185                 }
186                 else
187                 {
188                     x++;
189                     printf("%I64d\n",query(1,in[x],out[x]));
190                 }
191             }
192         }
193     return 0;
194 }
时间: 2024-08-24 04:43:34

HDU 5692 线段树+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]之间的所有节点都求出

J - Assign the task HDU - 3974 (线段树 + dfs序)

题意:给一颗树,两种操作,查询 i 结点的颜色,和将i结点和它的子树都染成另一种颜色 题解:dfs序构建线段树,对于x和其子树染色就是 l[x] 和 r[x]; dfs序线段树板子 #include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<algorithm> #include<cmath> #include<queue>

hdu 3974 Assign the task 线段树 DFS序

给你一棵树,每次修改一个子树的所有值,然后单点查询. 按照DFS序把节点排列(即在DFS中出现的先后次序),同一个子树在序列中连续. 1 #include <cstdio> 2 using namespace std; 3 typedef long long ll; 4 int n,q,T,Tc,cnt,sum; 5 int col[210000],lzy[210000],sta[51000],fin[51000]; 6 int nxt[51000],to[51000],head[51000]

HDU5692(线段树+dfs序)

Snacks Time Limit:5000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u Submit Status Description 百度科技园内有n个零食机,零食机之间通过n−1条路相互连通.每个零食机都有一个值v,表示为小度熊提供零食的价值. 由于零食被频繁的消耗和补充,零食机的价值v会时常发生变化.小度熊只能从编号为0的零食机出发,并且每个零食机至多经过一次.另外,小度熊会对某个零食机的零食有所偏爱,要求

【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