树剖板子8pts求调教
查看原帖
树剖板子8pts求调教
754502
_AyachiNene楼主2023/10/16 11:15
#include<bits/stdc++.h>
#define ls (root<<1)
#define rs (root<<1|1)
#define mid ((t[root].l+t[root].r)>>1)
using namespace std;
struct node
{
	int nxt,to,val,id;
}e[114514<<2];
int head[114514<<1],cnt_edge;
int w[114514<<1];
void add_edge(int u,int v,int w,int id)
{
	e[++cnt_edge].to=v;
	e[cnt_edge].val=w;
	e[cnt_edge].id=id;
	e[cnt_edge].nxt=head[u];
	head[u]=cnt_edge;
}
struct segt
{
	int l,r,tag,maxn,minn,sum;
}t[114514<<3];
void Swap(int root)
{
	t[root].sum*=-1;
	swap(t[root].maxn,t[root].minn);
	t[root].maxn*=-1,t[root].minn*=-1;
}
void update(int root)
{
	t[root].maxn=max(t[ls].maxn,t[rs].maxn);
	t[root].minn=min(t[ls].minn,t[rs].minn);
	t[root].sum=t[ls].sum+t[rs].sum;
}
void down(int root)
{
	t[ls].tag^=1;
	t[rs].tag^=1;
	Swap(ls);
	Swap(rs);
	t[root].tag=0;
}
void bld(int l,int r,int root)
{
	t[root].l=l;
	t[root].r=r;
	if(l==r)
	{
		t[root].maxn=t[root].maxn=t[root].sum=w[l];
		return;
	}
	bld(l,mid,ls);
	bld(mid+1,r,rs);
	update(root);
}
void add(int x,int y,int root)
{
	if(t[root].l>=x&&t[root].r<=y)
	{
		Swap(root);
		t[root].tag^=1;
		return;
	}
	if(t[root].tag)
		down(root);
	if(x<=mid)
		add(x,y,ls);
	if(y>mid)
		add(x,y,rs);
	update(root);
}
void add1(int x,int root,int k)
{
	if(t[root].l==t[root].r)
	{
		t[root].maxn=t[root].minn=t[root].sum=k;
		return;
	}
	if(t[root].tag)
		down(root);
	if(x<=mid)
		add1(x,ls,k);
	else
		add1(x,rs,k);
	update(root);
}
int query(int x,int y,int root)
{
	if(t[root].l>=x&&t[root].r<=y)
		return t[root].sum;
	int res=0;
	if(t[root].tag)
		down(root);
	if(x<=mid)
		res+=query(x,y,ls);
	if(y>mid)
		res+=query(x,y,rs);
	return res;
}
int qmax(int x,int y,int root)
{
	if(t[root].l>=x&&t[root].r<=y)
		return t[root].maxn;
	int res=-1e9;
	if(t[root].tag)
		down(root);
	if(x<=mid)
		res=max(res,qmax(x,y,ls));
	if(y>mid)
		res=max(res,qmax(x,y,rs));
	return res;
}
int qmin(int x,int y,int root)
{
	if(t[root].l>=x&&t[root].r<=y)
		return t[root].minn;
	int res=1e9;
	if(t[root].tag)
		down(root);
	if(x<=mid)
		res=min(res,qmin(x,y,ls));
	if(y>mid)
		res=min(res,qmin(x,y,rs));
	return res;
}
int siz[114514<<1],dep[114514<<1],f[114514<<1],son[114514<<1];
int dfn[114514<<1],top[114514<<1],cnt;
int pos[114514<<2];
int va[114514<<1];
void dfs1(int u,int fa)
{
	siz[u]=1;
	dep[u]=dep[fa]+1;
	for(int i=head[u];i;i=e[i].nxt)
	{
		int v=e[i].to;
		if(v==fa)
			continue;
		f[v]=u;
		dfs1(v,u);
		siz[u]+=siz[v];
		if(siz[v]>siz[son[u]])
			son[u]=v,va[u]=e[i].val;
	}
}
void dfs2(int u,int t,int val)
{
	dfn[u]=++cnt;
	top[u]=t;
	w[cnt]=val;
	if(son[u])
		dfs2(son[u],t,va[u]);
	for(int i=head[u];i;i=e[i].nxt)
	{
		int v=e[i].to;
		if(v!=f[u]&&v!=son[u])
			dfs2(v,v,e[i].val);
		pos[e[i].id]=v;
	}
}
void update_ver(int x,int y)
{
	add1(dfn[pos[x]],1,y);
}
void upt(int x,int y)
{
	while(top[x]!=top[y])
	{
		if(dep[top[x]]<dep[top[y]])
			swap(x,y);
		add(dfn[top[x]],dfn[x],1);
		x=f[top[x]];
	}
	if(dfn[x]>dfn[y])
		swap(x,y);
	add(dfn[x]+1,dfn[y],1);
}
int ask_sum(int x,int y)
{
	int res=0;
	while(top[x]!=top[y])
	{
		if(dep[top[x]]<dep[top[y]])
			swap(x,y);
		res+=query(dfn[top[x]],dfn[x],1);
		x=f[top[x]];
	}
	if(dfn[x]>dfn[y])
		swap(x,y);
	res+=query(dfn[x]+1,dfn[y],1);
	return res;
}
int ask_max(int x,int y)
{
	int res=-1e9;
	while(top[x]!=top[y])
	{
		if(dep[top[x]]<dep[top[y]])
			swap(x,y);
		res=max(qmax(dfn[top[x]],dfn[x],1),res);
		x=f[top[x]];
	}
	if(dfn[x]>dfn[y])
		swap(x,y);
	res=max(qmax(dfn[x]+1,dfn[y],1),res);
	return res;
}
int ask_min(int x,int y)
{
	int res=1e9;
	while(top[x]!=top[y])
	{
		if(dep[top[x]]<dep[top[y]])
			swap(x,y);
		res=min(qmin(dfn[top[x]],dfn[x],1),res);
		x=f[top[x]];
	}
	if(dfn[x]>dfn[y])
		swap(x,y);
	res=min(qmin(dfn[x]+1,dfn[y],1),res);
	return res;
}
int n,m;
int main()
{
	cin>>n;
	for(int i=1;i<n;i++)
	{
		int u,v,w;
		cin>>u>>v>>w;
		++u,++v;
		add_edge(u,v,w,i);
		add_edge(v,u,w,i);
	}
	dfs1(1,0);
	dfs2(1,1,0);
	bld(1,n,1);
	cin>>m;
	while(m--)
	{
		string op;
		int x,y;
		cin>>op>>x>>y;
		if(op=="C")
		{
			update_ver(x,y);
			continue;
		}
		++x,++y;
		if(op=="N")
			upt(x,y);
		else if(op=="SUM")
			cout<<ask_sum(x,y)<<endl;
		else if(op=="MAX")
			cout<<ask_max(x,y)<<endl;
		else
			cout<<ask_min(x,y)<<endl;
	}
}
2023/10/16 11:15
加载中...