2019.01.20【TJOI2015】【BZOJ3999】【洛谷P3976】旅游(LCT)

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

BZOJ传送门

洛谷传送门


解析:

这类路径问题LCT和链剖都能做,不过LCT空间常数较小而时间常数较大,链剖空间常数较大且复杂度不够优秀,但是时间常数优秀。

思路:

考虑LCT上每个Splay维护这一部分链的信息怎么更新。

首先需要记录最大值和最小值,用于计算最后的收益。

考虑定向统计,从深度小的向深度大的走。

由于 m a k e r o o t makeroot 操作的存在(主要是因为翻转),我们需要同时维护反向的答案。

那么我们就可以写出维护的函数 p u s h u p pushup 了,当然看上去有点窒息。。。

同时注意一点,由于我们维护了正反双向的答案,所以我们需要在打翻转标记的同时在这个节点上进行翻转操作,不然更新父亲节点的时候就会用到错误的答案。


代码:

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define re register
#define gc get_char
#define pc putchar
#define cs const

namespace IO{
	namespace IOONLY{
		cs int Rlen=1<<18|1;
		char buf[Rlen],*p1,*p2;
	}
	inline char get_char(){
		using namespace IOONLY;
		return (p1==p2)&&(p2=(p1=buf)+fread(buf,1,Rlen,stdin),p1==p2)?EOF:*p1++;
	}
	
	inline ll getint(){
		re ll num;
		re char c;
		while(!isdigit(c=gc()));num=c^48;
		while(isdigit(c=gc()))num=(num+(num<<2)<<1)+(c^48);
		return num;
	}
	inline void outint(ll a){
		static char ch[23];
		if(a==0)pc('0');
		while(a)ch[++ch[0]]=a-a/10*10,a/=10;
		while(ch[0])pc(ch[ch[0]--]^48);
	}
}
using namespace IO;

cs int N=50004;
int n;
int fa[N];
ll val[N];
int son[N][2];
ll mx[N],mn[N];
ll best[N],rbest[N],add[N];
bool rev[N];

inline bool which(int now){
	return son[fa[now]][1]==now;
}

inline bool isroot(int now){
	return !fa[now]||(son[fa[now]][0]!=now&&son[fa[now]][1]!=now);
}

inline void pushup(int now){
	mx[now]=mn[now]=val[now];
	best[now]=rbest[now]=0;
	re int lc=son[now][0],rc=son[now][1];
	if(lc){
		best[now]=max(best[now],best[lc]);
		best[now]=max(best[now],val[now]-mn[lc]);
		rbest[now]=max(rbest[now],rbest[lc]);
		rbest[now]=max(rbest[now],mx[lc]-val[now]);
		mn[now]=min(mn[now],mn[lc]);
		mx[now]=max(mx[now],mx[lc]);
	}
	if(rc){
		best[now]=max(best[now],best[rc]);
		best[now]=max(best[now],mx[rc]-val[now]);
		rbest[now]=max(rbest[now],rbest[rc]);
		rbest[now]=max(rbest[now],val[now]-mn[rc]);
		mn[now]=min(mn[now],mn[rc]);
		mx[now]=max(mx[now],mx[rc]);
	}
	if(lc&&rc){
		best[now]=max(best[now],mx[rc]-mn[lc]);
		rbest[now]=max(rbest[now],mx[lc]-mn[rc]);
	}
}

inline void pushadd(int now,int c){
	add[now]+=c;
	val[now]+=c;
	mn[now]+=c;
	mx[now]+=c;
}

inline void pushrev(int now){
	swap(son[now][0],son[now][1]);
	swap(best[now],rbest[now]);
	rev[now]^=1;
}

inline void pushdown(int now){
	if(rev[now]){
		if(son[now][0])pushrev(son[now][0]);
		if(son[now][1])pushrev(son[now][1]);
		rev[now]=0;
	}
	if(add[now]){
		if(son[now][0])pushadd(son[now][0],add[now]);
		if(son[now][1])pushadd(son[now][1],add[now]);
		add[now]=0;
	}
}

inline void Rotate(int now){
	int Fa=fa[now],FA=fa[Fa];
	bool pos=which(now);
	if(FA&&!isroot(Fa))son[FA][which(Fa)]=now;
	son[Fa][pos]=son[now][!pos];
	if(son[Fa][pos])fa[son[Fa][pos]]=Fa;
	son[now][!pos]=Fa;
	fa[Fa]=now;
	fa[now]=FA;
	pushup(Fa);
	pushup(now); 
}

inline void Splay(int now){
	static int q[N],qn;
	q[qn=1]=now;
	for(int re Fa=now;!isroot(Fa);Fa=fa[Fa])q[++qn]=fa[Fa];
	for(int re i=qn;i;--i)pushdown(q[i]);
	for(int re Fa=fa[now];!isroot(now);Rotate(now),Fa=fa[now])
	if(!isroot(Fa))Rotate(which(Fa)==which(now)?Fa:now);
}

inline void access(int now){
	for(int re ch=0;now;ch=now,now=fa[now])
	Splay(now),son[now][1]=ch,pushup(now);
}

inline void makeroot(int now){
	access(now);
	Splay(now);
	pushrev(now);
}

inline ll query(int u,int v){
	makeroot(u);
	access(v);
	Splay(v);
	return best[v];
}

inline void roadadd(int u,int v,ll c){
	makeroot(u);
	access(v);
	Splay(v);
	pushadd(v,c);
}

int last[N],nxt[N<<1],to[N<<1],ecnt;
inline void addedge(int u,int v){
	nxt[++ecnt]=last[u],last[u]=ecnt,to[ecnt]=v;
	nxt[++ecnt]=last[v],last[v]=ecnt,to[ecnt]=u;
}

void dfs(int u){
	for(int re e=last[u],v=to[e];e;v=to[e=nxt[e]])
	if(v^fa[u])fa[v]=u,dfs(v);
	pushup(u);
}

signed main(){
	n=getint();
	for(int re i=1;i<=n;val[i++]=getint());
	for(int re i=1;i++<n;addedge(getint(),getint()));
	dfs(1);
	for(int re Q=getint();Q--;pc('\n')){
		int u=getint(),v=getint();ll c=getint();
		outint(query(u,v));
		roadadd(u,v,c);
	}
	return 0;
}

猜你喜欢

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