HDU-5692 Snacks Segment Tree+dfs Sequence

Keywords: Linker

Topic link: Click to view

There are n snack machines in Baidu Science Park, which are connected by n_1 roads. Each snack machine has a value of v, which indicates the value of snacks for Koalas.

Because snacks are frequently consumed and supplemented, the value of snack machines v

It changes from time to time. Xiaoduxiong can only start from a snack machine numbered 0, and each snack machine passes through at most once. In addition, Xiaoduxiong will have a preference for snacks from a snack machine, requiring that snack machine be available on the route.

Plan a route for Little Bear to maximize the total value of the route.

Input

The first line of input data is an integer T(T < 10)

Represents T-group test data.

For each group of data, it contains two integers n,m(1 < n,m < 100000), which means there are n snack machines and m operations.

Next, in line n_1, there are two integers x and y(0 < x, y < n) in each line, indicating that the snack machine numbered x is connected to the snack machine numbered y.

The next line is composed of n numbers, representing the initial value v (| V | < 100000) of the snack machine numbered from 0 to n_1.

Next in line m, there are two operations: 0 x y, which means the value of the snack machine numbered x becomes y; 1 x, which means that the inquiry must be numbered x from the snack machine numbered 0.

In the course of the snack machine, the maximum value of the total.

This topic may be stack overflow, laborious students submit language selection c++, and add in the first line of the code:

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

Output

For each group of data, first output a line of "Case#?:". At the question mark, the number of groups of current data should be filled in, and the number of groups should be calculated from 1.

For each query, the output starts from a snack machine numbered 0 and must be numbered x.

In the course of the snack machine, the maximum value of the total.

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

Problem Solution: If we want to take a path through x from node 1, then the end point can only be the node of the branch of node x. Considering that when we step down from node 1, if we reach y, then the weight of the parent node of Y will be added. So we first run along the dfs sequence, first add the weight of each node to his children, and when we get it, we can directly get all the nodes of the branch x. Maximum is enough.

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e5+10;
struct node{
	int l,r;
	ll val,laz;
}tree[N<<2];
struct edge{
	int to,nex;
}e[N*2];
int n,m;
int val[N];
int head[N],len;
int in[N],out[N],p[N],cnt;
void init()
{
	len=cnt=0;
	for(int i=1;i<=n;i++)
		head[i]=-1;
}
void addedge(int x,int y)
{
	e[len].to=y;
	e[len].nex=head[x];
	head[x]=len++;
}
void dfs(int u,int fa)
{
	in[u]=++cnt;p[cnt]=u;
	int to;
	for(int i=head[u];~i;i=e[i].nex)
	{
		to=e[i].to;
		if(to==fa)continue;
		dfs(to,u);
	}
	out[u]=cnt;
}
void pushup(int cur)
{
	tree[cur].val=max(tree[cur<<1].val,tree[cur<<1|1].val);
}
void pushdown(int cur)
{
	if(tree[cur].laz)
	{
		tree[cur<<1].laz+=tree[cur].laz;
		tree[cur<<1|1].laz+=tree[cur].laz;
		tree[cur<<1].val+=tree[cur].laz;
		tree[cur<<1|1].val+=tree[cur].laz;
		tree[cur].laz=0;
	}
}
void build(int l,int r,int cur)
{
	tree[cur].l=l;
	tree[cur].r=r;
	tree[cur].val=0;
	tree[cur].laz=0;
	if(l==r)
	{
		return;
	}
	int mid=(r+l)>>1;
	build(l,mid,cur<<1);
	build(mid+1,r,cur<<1|1);
	pushup(cur);
}
void update(int pl,int pr,int cur,ll val)
{
	if(pl<=tree[cur].l&&tree[cur].r<=pr)
	{
		tree[cur].val+=val;
		tree[cur].laz+=val;
		return;
	}
	pushdown(cur);
	if(pl<=tree[cur<<1].r) update(pl,pr,cur<<1,val);
	if(pr>=tree[cur<<1|1].l)update(pl,pr,cur<<1|1,val);
	pushup(cur);
}
ll query(int pl,int pr,int cur)
{
	if(pl<=tree[cur].l&&tree[cur].r<=pr)
	{
		return tree[cur].val;
	}
	pushdown(cur);
	ll res=-1e18;
	if(pl<=tree[cur<<1].r) res=max(res,query(pl,pr,cur<<1));
	if(pr>=tree[cur<<1|1].l) res=max(res,query(pl,pr,cur<<1|1));
	return res;
}
int main()
{
	int T,nn=1;
	scanf("%d",&T);
	while(T--)
	{
		scanf("%d%d",&n,&m);
		init();
		int x,y;
		for(int i=1;i<n;i++)
		{
			scanf("%d%d",&x,&y);
			x++;y++;
			addedge(x,y);
			addedge(y,x);
		}
		dfs(1,0);
		build(1,n,1);
		for(int i=1;i<=n;i++)
		{
			scanf("%d",&val[i]);
			update(in[i],out[i],1,val[i]);
		}
		
		int op;
		printf("Case #%d:\n",nn++);
		for(int i=1;i<=m;i++)
		{
			scanf("%d",&op);
			if(op==1)
			{
				scanf("%d",&x);x++;
				printf("%lld\n",query(in[x],out[x],1));
			}
			else
			{
				scanf("%d%d",&x,&y);x++;
				update(in[x],out[x],1,y-val[x]);
				val[x]=y;
			}
		}
		
	} 
	return 0;
}

 

Posted by Kevin3374 on Wed, 15 May 2019 12:06:13 -0700