又是一个爆零求助于
查看原帖
又是一个爆零求助于
412902
laplace_oo楼主2022/9/20 21:19

rt

#include<bits/stdc++.h>

#define int long long

using namespace std;

struct Edge
{
	int v,w,nxt;
};

struct Tree
{
#define lc (p<<1)
#define rc ((p<<1)|1)
	int l,r;
	int mx;
	int add,cov;

	int length()
	{
		return (r-l+1);
	}
};

const int N=1000005;

int head[N],cntEdge;

int cntDfs;
int fa[N],ch[N],siz[N];
int dep[N],top[N],dfn[N];
int val[N],var[N],idv[N];

Edge e[N<<1];
Tree t[N<<2];

void addEdge(int u,int v,int w=0)
{
	cntEdge++;
	e[cntEdge].v=v;
	e[cntEdge].w=w;
	e[cntEdge].nxt=head[u];
	head[u]=cntEdge;
}

void dfs1(int u,int f)
{
	fa[u]=f;
	siz[u]=1;
	dep[u]=dep[f]+1;
	for(int i=head[u];i;i=e[i].nxt)
	{
		int v=e[i].v;
		int w=e[i].w;
		if(v==f)
			continue;
		dfs1(v,u);
		idv[(i+1)>>1]=v;
		var[v]=w;
		siz[u]+=siz[v];
		if(siz[v]>siz[ch[u]])
			ch[u]=v;
	}
}

void dfs2(int u,int f)
{
	top[u]=f;
	dfn[u]=++cntDfs;
	val[cntDfs]=var[u];
	if(ch[u])
		dfs2(ch[u],f);
	for(int i=head[u];i;i=e[i].nxt)
	{
		int v=e[i].v;
		if(v!=fa[u]&&v!=ch[u])
			dfs2(v,v);
	}
}

void pushUp(int p)
{
	t[p].mx=max(t[lc].mx,t[rc].mx);
}

void update(int p,int k)
{
	t[p].mx=k;
	t[p].cov=k;
	t[p].add=0;
}

void pushDown(int p)
{
	if(t[p].cov!=-1)
	{
		update(lc,t[p].cov);
		update(rc,t[p].cov);
		t[p].cov=-1;
	}
	t[lc].mx+=t[p].add;
	t[lc].add+=t[p].add;
	t[rc].mx+=t[p].add;
	t[rc].add+=t[p].add;
	t[p].add=0;
}

void build(int p,int x,int y)
{
	t[p].l=x,t[p].r=y;
	t[p].cov=-1;
	if(x==y)
	{
		t[p].mx=val[x];
		return;
	}
	int mid=(x+y)>>1;
	build(lc,x,mid);
	build(rc,mid+1,y);
	pushUp(p);
}

void change(int p,int pos,int k)
{
	if(pos<t[p].l||t[p].r<pos)
		return;
	if(t[p].l==t[p].r)
	{
		t[p].mx=k;
		t[p].cov=-1;
		t[p].add=0;
		return;
	}
	pushDown(p);
	change(lc,pos,k);
	change(rc,pos,k);
	pushUp(p);
}

void cover(int p,int x,int y,int k)
{
	if(y<t[p].l||t[p].r<x)
		return;
	if(x<=t[p].l&&t[p].r<=y)
	{
		update(p,k);
		return;
	}
	pushDown(p);
	cover(lc,x,y,k);
	cover(rc,x,y,k);
	pushUp(p);
}

void increase(int p,int x,int y,int k)
{
	if(y<t[p].l||t[p].r<x)
		return;
	if(x<=t[p].l&&t[p].r<=y)
	{
		t[p].mx+=k;
		t[p].add+=k;
		return;
	}
	pushDown(p);
	increase(lc,x,y,k);
	increase(rc,x,y,k);
	pushUp(p);
}

int getMax(int p,int x,int y)
{
	if(y<t[p].l||t[p].r<x)
		return LONG_LONG_MIN;
	if(x<=t[p].l&&t[p].r<=y)
		return t[p].mx;
	pushDown(p);
	return max(getMax(lc,x,y),getMax(rc,x,y));
}

void increaseRange(int x,int y,int k)
{
	while(top[x]!=top[y])
	{
		if(dep[top[x]<dep[top[y]]])
			swap(x,y);
		increase(1,dfn[top[x]],dfn[x],k);
		x=fa[top[x]];
	}
	if(dep[x]<dep[y])
		swap(x,y);
	increase(1,dfn[y]+1,dfn[x],k);
}

void coverRange(int x,int y,int k)
{
	while(top[x]!=top[y])
	{
		if(dep[top[x]]<dep[top[y]])
			swap(x,y);
		cover(1,dfn[top[x]],dfn[x],k);
		x=fa[top[x]];
	}
	if(dep[x]<dep[y])
		swap(x,y);
	cover(1,dfn[y]+1,dfn[x],k);
}

int getRangeMax(int x,int y)
{
	int res=LONG_LONG_MIN;
	while(top[x]!=top[y])
	{
		if(dep[top[x]]<dep[top[y]])
			swap(x,y);
		res=max(res,getMax(1,dfn[top[x]],dfn[x]));
		x=fa[top[x]];
	}
	if(dep[x]<dep[y])
		swap(x,y);
	res=max(res,getMax(1,dfn[y]+1,dfn[x]));
	return res;
}

signed main()
{
	// freopen("cao.in","r",stdin);
	// freopen("madan.out","w",stdout);

	int n;
	cin>>n;
	for(int i=2;i<=n;++i)
	{
		int iu,iv,iw;
		cin>>iu>>iv>>iw;
		addEdge(iu,iv,iw);
		addEdge(iv,iu,iw);
	}
	
	dfs1(1,0);
	dfs2(1,1);
	build(1,1,n);

	string io;
	do
	{
		cin>>io;
		if(io=="Change")
		{
			int ik,iw;
			cin>>ik>>iw;
			change(1,dfn[idv[(ik+1)>>1]],iw);
		}
		if(io=="Cover")
		{
			int iu,iv,iw;
			cin>>iu>>iv>>iw;
			coverRange(iu,iv,iw);
		}
		if(io=="Add")
		{
			int iu,iv,iw;
			cin>>iu>>iv>>iw;
			increaseRange(iu,iv,iw);
		}
		if(io=="Max")
		{
			int iu,iv;
			cin>>iu>>iv;
			cout<<getRangeMax(iu,iv)<<endl;
		}
	}while(io!="Stop");

	return 0;
}

2022/9/20 21:19
加载中...