2019.03.24【SPOJ-GSS7】Can you answer these queries VII(LCT)

版权声明:转载请声明出处,谢谢配合。 https://blog.csdn.net/zxyoi_dreamer/article/details/88784587

传送门


解析

LCT维护GSS系列操作不想解释。。。


代码:

#include<bits/stdc++.h>
#define ll long long
#define re register
#define gc get_char
#define cs const

namespace IO{
	inline char get_char(){
		static cs int Rlen=1<<20|1;
		static char buf[Rlen],*p1,*p2;
		return (p1==p2)&&(p2=(p1=buf)+fread(buf,1,Rlen,stdin),p1==p2)?EOF:*p1++;
	}
	
	inline int getint(){
		re char c;
		re bool f=0;
		while(!isdigit(c=gc()))f^=c=='-';re int num=c^48;
		while(isdigit(c=gc()))num=(num+(num<<2)<<1)+(c^48);
		return f?-num:num;
	}
}
using namespace IO;

using std::cout;
using std::cerr;

inline int max(int a,int b){return a<b?b:a;}

struct node{
	int lmx,rmx,mx,sum;
	node(){}
	node(cs int &_val){lmx=rmx=mx=max(sum=_val,0);}
	friend node operator+(cs node &l,cs node &r){
		node t;
		t.sum=l.sum+r.sum;
		t.lmx=max(l.lmx,l.sum+r.lmx);
		t.rmx=max(r.rmx,r.sum+l.rmx);
		t.mx=max(max(l.mx,r.mx),l.rmx+r.lmx);
		return t;
	}
};

cs int N=1e5+5;

std::vector<int> e[N];
inline void addedge(int u,int v){
	e[u].push_back(v);
	e[v].push_back(u);
}

namespace LCT{
	int son[N][2],fa[N],siz[N];
	node t[N];
	int val[N];
	bool rev[N],tag[N];
	
	inline void pushup(int u){
		siz[u]=siz[son[u][0]]+siz[son[u][1]]+1;
		t[u]=t[son[u][0]]+node(val[u])+t[son[u][1]];
	}
	
	inline void pushrev(int u){
		rev[u]^=1;
		std::swap(son[u][0],son[u][1]);
		std::swap(t[u].lmx,t[u].rmx);
	}
	inline void pushcover(int u,int _val){
		tag[u]=1;
		t[u]=node(_val*siz[u]);
		val[u]=_val;
	}
	
	inline void pushdown(int u){
		if(rev[u]){
			if(son[u][0])pushrev(son[u][0]);
			if(son[u][1])pushrev(son[u][1]);
			rev[u]=0;
		}
		if(tag[u]){
			if(son[u][0])pushcover(son[u][0],val[u]);
			if(son[u][1])pushcover(son[u][1],val[u]);
			tag[u]=0;
		}
	}
	
	inline bool which(int u){return son[fa[u]][1]==u;}
	inline bool isroot(int u){return son[fa[u]][0]!=u&&son[fa[u]][1]!=u;}
	
	inline void Rotate(int u){
		int Fa=fa[u],FA=fa[Fa];
		bool pos=which(u);
		if(!isroot(Fa))son[FA][which(Fa)]=u;
		son[Fa][pos]=son[u][!pos];
		if(son[Fa][pos])fa[son[Fa][pos]]=Fa;
		son[u][!pos]=Fa;
		fa[Fa]=u;fa[u]=FA;
		pushup(Fa);pushup(u);
	}
	
	inline void Splay(int u){
		static int q[N],qn;
		q[qn=1]=u;
		for(int re Fa=u;!isroot(Fa);Fa=fa[Fa])q[++qn]=fa[Fa];
		while(qn)pushdown(q[qn--]);
		for(int re Fa=fa[u];!isroot(u);Rotate(u),Fa=fa[u])
		if(!isroot(Fa))Rotate(which(Fa)==which(u)?Fa:u);
	}
	inline void access(int u){
		for(int re ch=0;u;u=fa[ch=u])
		Splay(u),son[u][1]=ch,pushup(u);
	}
	
	inline void makeroot(int u){
		access(u);Splay(u);
		pushrev(u);
	}
	
	inline int query(int u,int v){
		makeroot(u);
		access(v);
		Splay(v);
		return t[v].mx;
	}
	
	inline void cover(int u,int v,int val){
		makeroot(u);
		access(v);
		Splay(v);
		pushcover(v,val);
	}
	
}
using namespace LCT;

void dfs(int u){
	for(int &v:e[u])
	if(v!=fa[u])fa[v]=u,dfs(v);
}

int n;
signed main(){
	n=getint();
	for(int re i=1;i<=n;++i)t[i]=node(val[i]=getint());
	for(int re i=1;i<n;++i)addedge(getint(),getint());
	dfs(1);
	n=getint();
	while(n--)switch(getint()){
		case 1:{
			int u=getint(),v=getint();
			cout<<query(u,v)<<"\n";
			break;
		}
		case 2:{
			int u=getint(),v=getint(),val=getint();
			cover(u,v,val);
			break;
		}
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/zxyoi_dreamer/article/details/88784587