#12 T20秒,求调
查看原帖
#12 T20秒,求调
370251
liuhangxin楼主2022/8/11 16:41

rt,代码如下:

#include<bits/stdc++.h>
using namespace std;
const int N=4e5+10,inf=0x3f3f3f3f;
int n,m;
int h[2*N],e[2*N],ne[2*N],w[2*N],idx=1;
int size[N],root=1,zs=N,id[N],top[N],cnt,cnt2,cnt3;
int f[N],deep[N],egd[N],maxson[N];
int a[N],regd[N],id2[N],mark[4*N],id1[N];
struct node
{
	int l,r,maxv,minv,sum;
}t[4*N];
void add(int a,int b,int c)
{
	e[idx]=b;
	w[idx]=c;
	ne[idx]=h[a];
	h[a]=idx++;
}
void pushup2(node &a,node b,node c)
{
	a.minv=min(b.minv,c.minv);
	a.maxv=max(b.maxv,c.maxv);
	a.sum=b.sum+c.sum;
}
void pushup(int u)
{
	pushup2(t[u],t[2*u],t[2*u+1]);
}
void dfs1(int u,int fa)
{
	int zd=0;
	size[u]=1;
	for(int i=h[u];i!=-1;i=ne[i])
	{
		int v=e[i];
		if(v==fa)continue;
		dfs1(v,u);
		if(size[v]>zd)zd=size[v];
	}
	zd=max(zd,n-size[u]);
	if(zd<zs)zs=zd,root=u;
}
void dfs2(int u,int fa)
{
	int sum=0;
	size[u]=1;
	deep[u]=deep[fa]+1,f[u]=fa;
	for(int i=h[u];i!=-1;i=ne[i])
	{
		int v=e[i];
		if(v==fa)continue;
		dfs2(v,u);
		a[v]=w[i];
		id2[id1[i]]=v;
		size[u]+=size[v];
		if(size[v]>sum)sum=size[v],maxson[u]=v;
	}
}
void dfs3(int u)
{
	id[u]=cnt2,egd[u]=++cnt,regd[cnt]=u;
	if(maxson[u])dfs3(maxson[u]);
	for(int i=h[u];i!=-1;i=ne[i])
	{
		int v=e[i];
		if(id[v])continue;
		top[++cnt2]=v;
		dfs3(v);
	}
}
void build(int u,int l,int r)
{
	if(l==r)
	{
		t[u]={l,l,a[regd[l]],a[regd[l]],a[regd[l]]};
		return;
	}
	t[u]={l,r};
	int mid=(l+r)/2;
	build(2*u,l,mid);
	build(2*u+1,mid+1,r);
	pushup(u);
}
void pushdown(int u)
{
	int a=t[2*u].minv;
	t[2*u].minv=-t[2*u].maxv;
	t[2*u].maxv=-a;
	t[2*u].sum*=-1;
	mark[2*u]^=1;
	a=t[2*u+1].minv;
	t[2*u+1].minv=-t[2*u+1].maxv;
	t[2*u+1].maxv=-a;
	t[2*u+1].sum*=-1;
	mark[2*u+1]^=1;
	mark[u]=0;
}
void change(int u,int l,int r,int k)
{
	if(l<=t[u].l&&t[u].r<=r)
	{
		if(k!=inf)t[u].minv=t[u].maxv=t[u].sum=k;
		else
		{
			swap(t[u].maxv,t[u].minv);
			t[u].minv*=-1;
			t[u].maxv*=-1;
			t[u].sum*=-1;
			mark[u]^=1;
		}
		return;
	}
	if(mark[u])pushdown(u);
	int mid=(t[u].l+t[u].r)/2;
	if(l<=mid)change(2*u,l,r,k);
	if(r>mid)change(2*u+1,l,r,k);
	pushup(u);
}
int lca(int a,int b)
{
	while(id[a]!=id[b])
	{
		if(deep[top[id[a]]]<deep[top[id[b]]])swap(a,b);
		a=f[top[id[a]]];
	}
	return deep[a]<deep[b]?a:b;
}
void sumchange(int a,int b)
{
	while(id[a]!=id[b])
	{
		if(deep[top[id[a]]]<deep[top[id[b]]])swap(a,b);
		change(1,egd[top[id[a]]],egd[a],inf);
		a=f[top[id[a]]];
	}
	if(deep[a]<deep[b])swap(a,b);
	change(1,egd[b],egd[a],inf);
}
node ask(int u,int l,int r)
{
	if(l<=t[u].l&&t[u].r<=r)
		return t[u];
	if(mark[u])pushdown(u);
	int mid=(t[u].l+t[u].r)/2;
	node x;
	if(l<=mid&&mid<r)
	{
		node y=ask(2*u,l,r),z=ask(2*u+1,l,r);
		pushup2(x,y,z);
	}
	else if(l<=mid)x=ask(2*u,l,r);
	else x=ask(2*u+1,l,r);
	return x;
}
int sumask1(int a,int b)
{
	int sum=0;
	while(id[a]!=id[b])
	{
		if(deep[top[id[a]]]<deep[top[id[b]]])swap(a,b);
		sum+=ask(1,egd[top[id[a]]],egd[a]).sum;
		a=f[top[id[a]]];
	}
	if(deep[a]<deep[b])swap(a,b);
	sum+=ask(1,egd[b],egd[a]).sum;
	return sum;
}
int sumask2(int a,int b)
{
	int sum=-inf;
	while(id[a]!=id[b])
	{
		if(deep[top[id[a]]]<deep[top[id[b]]])swap(a,b);
		sum=max(sum,ask(1,egd[top[id[a]]],egd[a]).maxv);
		a=f[top[id[a]]];
	}
	if(deep[a]<deep[b])swap(a,b);
	sum=max(sum,ask(1,egd[b],egd[a]).maxv);
	return sum;
}
int sumask3(int a,int b)
{
	int sum=inf;
	while(id[a]!=id[b])
	{
		if(deep[top[id[a]]]<deep[top[id[b]]])swap(a,b);
		sum=min(sum,ask(1,egd[top[id[a]]],egd[a]).minv);
		a=f[top[id[a]]];
	}
	if(deep[a]<deep[b])swap(a,b);
	sum=min(sum,ask(1,egd[b],egd[a]).minv);
	return sum;
}
int find(int a,int b)
{
	while(id[a]!=id[b])
	{
		if(deep[top[id[a]]]<deep[top[id[b]]])swap(a,b);
		if(deep[top[id[a]]]==deep[b]+1)break;
		a=f[top[id[a]]];
	}
	if(deep[a]<deep[b])swap(a,b);
	while(f[a]!=b)a=f[a];
	return a;
}
int main()
{
	memset(h,-1,sizeof h);
	scanf("%d",&n);
	for(int i=1;i<n;i++)
	{
		int a,b,c;
		scanf("%d%d%d",&a,&b,&c);
		id1[idx]=id1[idx+1]=++cnt3;
		add(a,b,c),add(b,a,c);
	}
	dfs1(1,1);
	dfs2(root,root);
	top[++cnt2]=root;
	dfs3(root);
	build(1,1,n);
	scanf("%d",&m);
	char op[10];
	int a,b;
	for(int i=1;i<=m;i++)
	{
		scanf("%s%d%d",&op,&a,&b);
		if(op[0]=='C')
			change(1,egd[id2[a]],egd[id2[a]],b);
		else if(op[0]=='N')
		{
			int l=lca(a,b);
			change(1,egd[l],egd[l],inf);
			sumchange(a,b);
		}
		else 
		{
			int l=lca(a,b);
			if(l!=a&&l!=b)
			{
				int a2=a,b2=b;
				a2=find(a,l);
				b2=find(b,l);
				if(op[0]=='S')
					cout<<sumask1(a,a2)+sumask1(b,b2)<<endl;
				else if(op[1]=='A')
					cout<<max(sumask2(a,a2),sumask2(b,b2))<<endl;
				else if(op[1]=='I')
					cout<<min(sumask3(a,a2),sumask3(b,b2))<<endl;		
			}
			else
			{
				if(deep[a]<deep[b])swap(a,b);
				int c;
				c=find(a,l);
				if(op[0]=='S')
					cout<<sumask1(a,c)<<endl;
				else if(op[1]=='A')
					cout<<sumask2(a,c)<<endl;
				else if(op[1]=='I')
					cout<<sumask3(a,c)<<endl;	
			}
		}
	}
	return 0;
}
2022/8/11 16:41
加载中...