最大值崩了,跪求dalao
查看原帖
最大值崩了,跪求dalao
230808
Zxsoul楼主2020/11/14 17:27
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <vector>
using namespace std;
typedef long long ll;

const int manx=1e6+10;
const int mamx = 1e6 + 11;
const ll mod = 2123400401301379571;
const int inf = 0x3f3f3f3f;

inline int read() {
  char c = getchar(); int x = 0, f = 1;
  for ( ; !isdigit(c); c = getchar()) if (c == '-') f = -1;
  for ( ; isdigit(c); c = getchar()) x = x * 10 + (c ^ 48);
  return x * f;
}
struct node{
	int v,nxt;
}e[manx << 1];
int head[manx],cnt,n,m,val[manx];
int js,size_[manx],dep[manx],fa[manx],dfsn[manx],tp[manx],hson[manx],bz[manx];
char a[manx];
inline void add(int u,int v){
	e[++cnt].v = v;
	e[cnt].nxt = head[u];
	head[u] = cnt;
}
namespace Seg{
	#define ls i<<1
	#define rs i<<1|1
	struct node{
		int l,r;
		ll sum,lazy,mxa;
	}tr[manx<<2];
	inline void update(int i){
		 tr[i].sum = tr[ls].sum + tr[rs].sum;
		 tr[i].mxa = max(tr[ls].mxa ,tr[rs].mxa);
	} 
	inline void down(int i){
		if(tr[i].lazy){
			ll x = tr[i].lazy;
			tr[ls].sum = (tr[i].r - tr[i].l + 1)*x;
			tr[rs].sum = (tr[i].r - tr[i].l + 1)*x;
			tr[ls].lazy = x;
			tr[rs].lazy = x;// 写挂了 
			tr[ls].mxa = x;
			tr[rs].mxa = x; 
			tr[i].lazy = 0; 
		}
	}
	inline void build(int i,int l,int r){
	 	tr[i].l = l; tr[i].r = r;
	 	if(l == r){
	 		tr[i].sum = val[bz[l]];
	 		tr[i].mxa = val[bz[l]];
	 		return;
		 }
		 int mid = (l+r) >> 1;
		 build(ls, l, mid);
		 build(rs, mid+1, r);
		 update(i); 
	}
	inline void tree_add(int i,int l,int r,int add){
		if(tr[i].l >= l && tr[i].r <= r){
			tr[i].sum += (tr[i].r - tr[i].l + 1)*add;
			tr[i].lazy += add;
			return;
		}
		int mid = (tr[i].l + tr[i].r) >> 1;
		if(mid >= r) tree_add(ls,l,r,add);
		else if(mid < l) tree_add(rs,l,r,add);
			 else tree_add(ls,l,mid,add),tree_add(rs,mid+1,r,add);
		update(i); 
	}
	inline void tree_only_add(int i,int u,int add){
		if(tr[i].l  == tr[i].r ){
			tr[i].sum = add;
			return;
		}
		int mid = (tr[i].l + tr[i].r ) >> 1;
		if(mid >= u)tree_only_add(ls,u,add);
		else tree_only_add(rs,u,add);
		update(i);
	}
	inline ll tree_query(int i,int l,int r){
		if(tr[i].l >= l && tr[i].r <= r){
			return tr[i].sum ;
		}
		down(i);
		int mid = (tr[i].l + tr[i].r ) >> 1;
		if(mid >= r) return tree_query(ls, l, r) ;
		else if(mid < l) return tree_query(rs, l, r) ;
		update(i);
		return tree_query(ls, l, mid) + 
		       tree_query(rs, mid+1, r) ;
	}
	inline ll tree_max(int i,int l,int r){
		if(tr[i].l >= l && tr[i].r <= r){
			return tr[i].mxa ;
		}
		down(i);
		int mid = ( tr[i].l + tr[i].r ) >> 1;
		if(mid >= r) return tree_max (ls, l, r);
		else if(mid < l) return tree_max (rs, l, r);
		update(i); 
		return max( tree_max(ls,l,mid), tree_max(rs,mid+1,r) );
	}
	#undef ls
	#undef rs
} 
	inline void dfs1(int u,int pre,int d){
	 	fa[u] = pre; size_[u] = 1; dep[u] = d;
		 for(int i =head[u];i;i = e[i].nxt ){
		 	int v = e[i].v ;
		 	if(v != pre){
		 		dfs1(v,u,d+1);//深搜得到重儿子 
				size_[u] += size_[v];//每个子树的大小 
			 	if( !hson[u] || size_[ hson[u] ] < size_[v] )
			 		hson[u] = v;//没有重儿子或者当前子树大小比重儿子大,那么更新重儿子 
			 }
			 }
		 } 
	inline void dfs2(int u,int top){
		tp[u] = top; dfsn[u] = ++js;bz[js] = u;//得到DFSN,以便加入线段树 
		if(!hson[u]) return;//保证每一条重链都是在区间内连续 
		dfs2(hson[u],top);
		for(int i = head[u];i;i = e[i].nxt){
			int v = e[i].v;
			if(v != hson[u] && v != fa[u]){//既不是重儿子,也不是父亲,就重新开一条重链 
				dfs2(v,v);
			}
		}
	}
	inline void path_all_add(int u,int v,int val){
		while(tp[u] != tp[v]){
			if(dep[tp[u]] < dep[tp[v]]) swap(u,v);
			/*
			   思路做法同下 
			*/ 
			Seg::tree_add(1,dfsn[tp[u]],dfsn[u],val);
			u = fa[tp[u]];
		}
		if(dep[u] < dep[v]) swap(u,v);
		Seg::tree_add(1,dfsn[u],dfsn[v],val);
	}
inline ll path_query(int u,int v){
	ll ans = 0;
		while(tp[u] != tp[v]){//深度较深的先往上跳 
			if(dep[tp[u]] < dep[tp[v]])swap (u, v);//保证U永远都是上边的那一个点 
			ans += Seg::tree_query (1,dfsn[tp[u]],dfsn[u]);
			u = fa[ tp[u] ];//当前重链已经操作完成,继续操作在这条路径上的部分重链且重链与当前重链相连 
		}
		if(dep[u] > dep[v]) swap (u, v);
		/*
			两个重链循环完后会调到同一条链上,在进行特殊操作
		*/ 
		ans += Seg::tree_query (1, dfsn[u],dfsn[v]);
		return ans;
	}
	inline ll path_max(int u,int v){
		ll ans = 0;
		while(tp[u] != tp[v]){
			if(dep[ tp[u] ] < dep[ tp[v] ]) swap (u, v);
		    ll jj = Seg::tree_max (1, dfsn[tp[u]], dfsn[u]);
		    ans = max(jj, ans);
			u = fa[ tp[u] ]; 
		}
		if(dep[u] > dep[u]) swap(u,v);
		ll ooo = Seg::tree_max(1,dfsn[u],dfsn[v]);
		ans = max(ooo,ans);
		return ans;
	}
int main(){
	n = read();
	for(int i = 1;i < n; i++){
		int x = read(),y = read();
		add(x,y);
		add(y,x);
	}
	for(int i = 1;i <= n; i++){
		val[i] = read();	
	}
	m = read();
	dfs1(1,0,1),
	dfs2(1,1),	
	Seg::build(1,1,n);
	while(m--){
		cin>>a;
		int x,y;
		if(a[1]=='M'){
			x = read(); y = read();
			cout<<path_max(x,y)<<endl;	
		}	
		if(a[1]=='S'){
			x = read(); y = read();
			cout<<path_query(x,y)<<endl;
		}
		if(a[1]=='H'){
			x = read(); y = read();
			Seg::tree_only_add(1,x,y);
		}
	}
	return 0;
}


2020/11/14 17:27
加载中...