MnZn求助树剖#1~#10mle,#12wa,#11 ac,悬赏7关注
查看原帖
MnZn求助树剖#1~#10mle,#12wa,#11 ac,悬赏7关注
529038
Butterfly__qwq楼主2023/9/26 15:39
#include<bits/stdc++.h>
using namespace std;
const int N=200005;
int n,m,idx,cnt,qwq=1,w[N],fa[N],dep[N],sz[N],son[N],dfn[N],top[N],rk[N],dfe[N],ue[N];
int head[N];
struct edge
{
	int to,next,w,id;
}e[N];
struct node
{
	int lc,rc,mx,mn,sum,lazy;
}sg[N<<1];
void pushup(int u)
{
	sg[u].sum=sg[sg[u].lc].sum+sg[sg[u].rc].sum;
	sg[u].mx=max(sg[sg[u].lc].mx,sg[sg[u].rc].mx);
	sg[u].mn=min(sg[sg[u].lc].mn,sg[sg[u].rc].mn);
}
void pushlazy(int u)
{
	sg[u].lazy^=1;
	sg[u].mn^=sg[u].mx^=sg[u].mn^=sg[u].mx;
	sg[u].sum=-sg[u].sum;
	sg[u].mn=-sg[u].mn;
	sg[u].mx=-sg[u].mx;
}
void pushdown(int u)
{
	if(sg[u].lazy)
	{
		pushlazy(sg[u].lc);
		pushlazy(sg[u].rc);
		sg[u].lazy=0;
	}
}
void build(int u,int l,int r)
{
	if(l==r)
	{
		sg[u].sum=sg[u].mx=sg[u].mn=w[rk[l]];
		return;
	}
	int mid=l+r>>1;
	sg[u].lc=++qwq;
	build(qwq,l,mid);
	sg[u].rc=++qwq;
	build(qwq,mid+1,r);
	pushup(u);
}
void update(int u,int l,int r,int s,int w)
{
	if(l==r)
	{
		sg[u].sum=sg[u].mx=sg[u].mn=w;
		return;
	}
	pushdown(u);
	int mid=l+r>>1;
	if(s<=mid)update(sg[u].lc,l,mid,s,w);
	else update(sg[u].rc,mid+1,r,s,w);
	pushup(u);
}
void nega(int u,int l,int r,int L,int R)
{
	if(L<=l&&r<=R)
	{
		pushlazy(u);
		return;
	}
	int mid=l+r>>1;
	if(L<=mid)nega(sg[u].lc,l,mid,L,R);
	if(R>mid)nega(sg[u].rc,mid+1,r,L,R);
	pushup(u);
}
int querys(int u,int l,int r,int L,int R)
{
	if(L<=l&&r<=R)return sg[u].sum;
	pushdown(u);
	int mid=l+r>>1;
	if(R<=mid)return querys(sg[u].lc,l,mid,L,R);
	if(L>mid)return querys(sg[u].rc,mid+1,r,L,R);
	return querys(sg[u].lc,l,mid,L,R)+querys(sg[u].rc,mid+1,r,L,R);
}
int queryx(int u,int l,int r,int L,int R)
{
	if(L<=l&&r<=R)return sg[u].mx;
	pushdown(u);
	int mid=l+r>>1;
	if(R<=mid)return queryx(sg[u].lc,l,mid,L,R);
	if(L>mid)return queryx(sg[u].rc,mid+1,r,L,R);
	return max(queryx(sg[u].lc,l,mid,L,R),queryx(sg[u].rc,mid+1,r,L,R));
}
int queryn(int u,int l,int r,int L,int R)
{
	if(L<=l&&r<=R)return sg[u].mn;
	pushdown(u);
	int mid=l+r>>1;
	if(R<=mid)return queryn(sg[u].lc,l,mid,L,R);
	if(L>mid)return queryn(sg[u].rc,mid+1,r,L,R);
	return min(queryn(sg[u].lc,l,mid,L,R),queryn(sg[u].rc,mid+1,r,L,R));
}
void add(int u,int v,int w,int id)
{
	e[++cnt]={v,head[u],w,id};
	head[u]=cnt;
	e[++cnt]={u,head[v],w,id};
	head[v]=cnt;
}
void dfs1(int u,int f,int d)
{
	fa[u]=f;
	dep[u]=d;
	sz[u]=1;
	son[u]=n;
	for(int i=head[u];i;i=e[i].next)
	{
		int v=e[i].to,w=e[i].w,id=e[i].id;
		if(v==f)continue;
		::w[v]=w;
		ue[v]=id;
		dfs1(v,u,d+1);
		sz[u]+=sz[v];
		if(sz[v]>sz[son[u]])son[u]=v;
	}
}
void dfs2(int u,int topfa)
{
	dfn[u]=dfe[ue[u]]=++idx;
	top[u]=topfa;
	rk[idx]=u;
	if(son[u]!=n)dfs2(son[u],topfa);
	for(int i=head[u];i;i=e[i].next)
	{
		int v=e[i].to;
		if(v==fa[u]||v==son[u])continue;
		dfs2(v,v);
	}
}
void nego(int u,int v)
{
	while(top[u]!=top[v])
	{
		if(dep[top[u]]<dep[top[v]])u^=v^=u^=v;
		nega(1,1,n,dfn[top[u]],dfn[u]);
		u=fa[top[u]];
	}
	if(dfn[u]>dfn[v])u^=v^=u^=v;
	nega(1,1,n,dfn[u],dfn[v]);
}
int queris(int u,int v)
{
	int res=0;
	while(top[u]!=top[v])
	{
		if(dep[top[u]]<dep[top[v]])u^=v^=u^=v;
		res+=querys(1,1,n,dfn[top[u]],dfn[u]);
		u=fa[top[u]];
	}
	if(dfn[u]>dfn[v])u^=v^=u^=v;
	res+=querys(1,1,n,dfn[u]+1,dfn[v]);
	return res;
}
int querix(int u,int v)
{
	int res=-1005;
	while(top[u]!=top[v])
	{
		if(dep[top[u]]<dep[top[v]])u^=v^=u^=v;
		res=max(res,queryx(1,1,n,dfn[top[u]],dfn[u]));
		u=fa[top[u]];
	}
	if(dfn[u]>dfn[v])u^=v^=u^=v;
	res=max(res,queryx(1,1,n,dfn[u]+1,dfn[v]));
	return res;
}
int querin(int u,int v)
{
	int res=1005;
	while(top[u]!=top[v])
	{
		if(dep[top[u]]<dep[top[v]])u^=v^=u^=v;
		res=min(res,queryn(1,1,n,dfn[top[u]],dfn[u]));
		u=fa[top[u]];
	}
	if(dfn[u]>dfn[v])u^=v^=u^=v;
	res=min(res,queryn(1,1,n,dfn[u]+1,dfn[v]));
	return res;
}
int main()
{
	cin>>n;
	for(int i=1,u,v,w;i<n;i++)
	{
		cin>>u>>v>>w;
		add(u,v,w,i);
	}
	dfs1(0,n,0);
	dfs2(0,0);
	build(1,1,n);
	cin>>m;
	string op;
	int u,v;
	while(m--)
	{
		cin>>op>>u>>v;
		if(op=="C")update(1,1,n,dfe[u],v);
		if(op=="N")nego(u,v);
		if(op=="SUM")cout<<queris(u,v)<<'\n';
		if(op=="MAX")cout<<querix(u,v)<<'\n';
		if(op=="MIN")cout<<querin(u,v)<<'\n';
	}
}
2023/9/26 15:39
加载中...