这都能过?
查看原帖
这都能过?
371309
Z_X_D_楼主2023/9/29 20:27

树剖第一遍dfs结点sz初值写错了设的0,但是判了重儿子编号为0就换一个重儿子,相当于是随便选了一个子结点当重儿子,但是过了(

提交寄录

#include<bits/stdc++.h>
#define ll long long
#define inf 1000000000
#define otto auto
#define N 200010
using namespace std;
struct E
{
	int to,w,ne,nb;
}e[N<<1];
struct R
{
	int ls,rs;
	int lz,zs,fs,ma,mi;
}t[N<<2];
int n,ct,tt;
int fa[N],nt[N],bl[N],et[N],tp[N],sz[N],hs[N];
int d[N],h[N],a[N];
void ade(int x,int y,int w,int i)
{
	e[++ct].to=y;
	e[ct].w=w;
	e[ct].nb=i;
	e[ct].ne=h[x];
	h[x]=ct;
}
void pu(int x)
{
	int ls=t[x].ls,rs=t[x].rs;
	t[x].ma=max(t[ls].ma,t[rs].ma);
	t[x].mi=min(t[ls].mi,t[rs].mi);
	t[x].zs=t[ls].zs+t[rs].zs;
	t[x].fs=t[ls].fs+t[rs].fs; 
}
void chg(int x)
{
	swap(t[x].ma,t[x].mi);
	swap(t[x].fs,t[x].zs);
	t[x].zs=-t[x].zs;
	t[x].fs=-t[x].fs;
	t[x].ma=-t[x].ma;
	t[x].mi=-t[x].mi;
	t[x].lz^=1;
}
void pd(int x)
{
	if(!t[x].lz)return;
	chg(t[x].ls);
	chg(t[x].rs);
	t[x].lz=0;
}
void dfs(int x)
{
	sz[x]=0;
	int i,y;
	for(i=h[x];i;i=e[i].ne)
	{
		y=e[i].to;
		if(y==fa[x])continue;
		fa[y]=x;
		d[y]=d[x]+1;
		a[y]=e[i].w;
		et[e[i].nb]=y;
		dfs(y);
		sz[x]+=sz[y];
		if(sz[y]>sz[hs[x]]||!hs[x])hs[x]=y;
	}
}
void dfss(int x,int t)
{
	tp[x]=t;
	if(x)
	{
		bl[x]=++ct;
		nt[ct]=x;
	}
	if(hs[x])dfss(hs[x],t);
	int y,i;
	for(i=h[x];i;i=e[i].ne)
	{
		y=e[i].to;
		if(y==fa[x]||y==hs[x])continue;
		dfss(y,y);
	}
}
int bu(int l,int r)
{
	int x=++tt;
	if(l==r)
	{
		if(a[nt[l]]>=0)
			t[x].zs=a[nt[l]];
		else
			t[x].fs=a[nt[l]];
		t[x].ma=t[x].mi=a[nt[l]];
		return x;
	}
	int mid=(l+r)>>1;
	t[x].ls=bu(l,mid);
	t[x].rs=bu(mid+1,r);
	pu(x);
	return x;
}
void upd(int x,int l,int r,int k,int w)
{
	if(l==r)
	{
		t[x].ma=t[x].mi=w;
		t[x].zs=t[x].fs=0;
		if(w>=0)t[x].zs=w;
		else t[x].fs=w;
		return;
	}
	pd(x);
	int mid=(l+r)>>1;
	if(k<=mid)upd(t[x].ls,l,mid,k,w);
	else upd(t[x].rs,mid+1,r,k,w);
	pu(x);
}
int qry(int x,int l,int r,int le,int ri)
{
	if(l>=le&&r<=ri)return t[x].zs+t[x].fs;
//	printf("%d l:%d r:%d le:%d ri:%d\n",x,l,r,le,ri);
	pd(x);
	int mid=(l+r)>>1,ans=0;
	if(le<=mid)ans+=qry(t[x].ls,l,mid,le,ri);
	if(ri>mid)ans+=qry(t[x].rs,mid+1,r,le,ri);
	pu(x);
	return ans;
}
int qma(int x,int l,int r,int le,int ri)
{
	if(l>=le&&r<=ri)return t[x].ma;
	pd(x);
	int mid=(l+r)>>1,ans=-inf;
	if(le<=mid)ans=max(ans,qma(t[x].ls,l,mid,le,ri));
	if(ri>mid)ans=max(ans,qma(t[x].rs,mid+1,r,le,ri));
	pu(x);
	return ans;
}
int qmi(int x,int l,int r,int le,int ri)
{
	if(l>=le&&r<=ri)return t[x].mi;
	pd(x);
	int mid=(l+r)>>1,ans=inf;
	if(le<=mid)ans=min(ans,qmi(t[x].ls,l,mid,le,ri));
	if(ri>mid)ans=min(ans,qmi(t[x].rs,mid+1,r,le,ri));
	pu(x);
	return ans;
}
void urt(int x,int l,int r,int le,int ri)
{
	if(l>=le&&r<=ri)
	{
		chg(x);
		return;
	}
	pd(x);
	int mid=(l+r)>>1;
	if(le<=mid)urt(t[x].ls,l,mid,le,ri);
	if(ri>mid)urt(t[x].rs,mid+1,r,le,ri);
	pu(x);
	return;
}
void rtl(int x,int y)
{
	while(tp[x]!=tp[y])
	{
		if(d[tp[x]]<d[tp[y]])swap(x,y);
		urt(1,1,n,bl[tp[x]],bl[x]);
		x=fa[tp[x]];
	}
	if(x==y)return;
	if(d[x]>d[y])swap(x,y);
	urt(1,1,n,bl[hs[x]],bl[y]);
}
int qrl(int x,int y)
{
	int ans=0;
	while(tp[x]!=tp[y])
	{
		if(d[tp[x]]<d[tp[y]])swap(x,y);
		ans+=qry(1,1,n,bl[tp[x]],bl[x]);
		x=fa[tp[x]];
	}
	if(x==y)return ans;
	if(d[x]>d[y])swap(x,y);
	ans+=qry(1,1,n,bl[hs[x]],bl[y]);
	return ans;
}
int qal(int x,int y)
{
	int ans=-inf;
	while(tp[x]!=tp[y])
	{
		if(d[tp[x]]<d[tp[y]])swap(x,y);
		ans=max(ans,qma(1,1,n,bl[tp[x]],bl[x]));
		x=fa[tp[x]];
	}
	if(x==y)return ans;
	if(d[x]>d[y])swap(x,y);
	ans=max(ans,qma(1,1,n,bl[hs[x]],bl[y]));
	return ans;
}
int qil(int x,int y)
{
	int ans=inf;
	while(tp[x]!=tp[y])
	{
		if(d[tp[x]]<d[tp[y]])swap(x,y);
		ans=min(ans,qmi(1,1,n,bl[tp[x]],bl[x]));
		x=fa[tp[x]];
	}
	if(x==y)return ans;
	if(d[x]>d[y])swap(x,y);
	ans=min(ans,qmi(1,1,n,bl[hs[x]],bl[y]));
	return ans;
}
signed main()
{
	int i,q,x,y,w;
	string s;
	scanf("%d",&n);
	for(i=1;i<n;i++)
	{
		scanf("%d%d%d",&x,&y,&w);
		ade(x,y,w,i);
		ade(y,x,w,i);
	}
	dfs(0);
	ct=0;
	dfss(0,0);
	n--;
	bu(1,n);
	scanf("%d",&q);
	while(q--)
	{
		cin>>s;
		scanf("%d%d",&x,&y);
		if(s=="C")
			upd(1,1,n,bl[et[x]],y);
		if(s=="N")
			rtl(x,y);
		if(s=="SUM")
			printf("%d\n",qrl(x,y));
		if(s=="MAX")
			printf("%d\n",qal(x,y));
		if(s=="MIN")
			printf("%d\n",qil(x,y));
	}
	return 0;
}
2023/9/29 20:27
加载中...