记录编号 532430 评测结果 AAAAAAAAAA
题目名称 [国家集训队2011]旅游 最终得分 100
用户昵称 GravatarHale 是否通过 通过
代码语言 C++ 运行时间 0.380 s
提交时间 2019-05-29 19:53:11 内存使用 33.50 MiB
显示代码纯文本
#include<bits/stdc++.h>
#define ls(x) x<<1
#define rs(x) x<<1|1
using namespace std;
const int N=2e5+7;
const int INF=0x7f7f7f;
int m,n,root,cnt,idx,tot,ans;
int son[N],fa[N],size[N],v[N],vt[N],a[N],b[N],dep[N],top[N],id[N],head[N];
struct edge
{
	int nx,to,dist;
} e[N];
struct node
{
	int sum,mx,mn;
} t[N<<2];
void add_edge(int a,int b,int dist)
{
	cnt++;e[cnt].nx=head[a];e[cnt].to=b;e[cnt].dist=dist;head[a]=cnt;
	cnt++;e[cnt].nx=head[b];e[cnt].to=a;e[cnt].dist=dist;head[b]=cnt;
}
int read()
{
	int x=0,f=1;char ch=getchar();
	while (ch<'0'||ch>'9') {if (ch=='-') f=-1;ch=getchar();}
	while (ch>='0'&&ch<='9') {x=x*10+ch-'0';ch=getchar();}
	return x*f;
}
void dfs1(int x,int ff,int deep)
{
	dep[x]=deep;
	fa[x]=ff;
	size[x]=1;
	for (int i=head[x];i;i=e[i].nx)
	{
		int y=e[i].to;
		if (y==ff) continue;
		vt[y]=e[i].dist;
		dfs1(y,x,deep+1);
		size[x]+=size[y];
		if (size[y]>size[son[x]]) son[x]=y;
	}
}
void dfs2(int x,int topf)
{
	top[x]=topf;
	id[x]=++idx;
	v[idx]=vt[x];
	if (!son[x]) return;
	dfs2(son[x],topf);
	for (int i=head[x];i;i=e[i].nx)
	{
		int y=e[i].to;
		if (y==son[x]||y==fa[x]) continue;
		dfs2(y,y);
	}
}

void push_up(int p)
{
	t[p].sum=t[ls(p)].sum+t[rs(p)].sum;
	t[p].mn=min(t[ls(p)].mn,t[rs(p)].mn);
	t[p].mx=max(t[ls(p)].mx,t[rs(p)].mx);
}
void build(int p,int l,int r)
{
	if (l==r) {t[p].sum=t[p].mn=t[p].mx=v[l];return;}
	int mid=(l+r)>>1;
	build(ls(p),l,mid);
	build(rs(p),mid+1,r);
	push_up(p);
}
void update(int nl,int nr,int l,int r,int p)
{
	if (l==r) 
	{
		t[p].sum=-t[p].sum;
		t[p].mn=-t[p].mn;
		t[p].mx=-t[p].mx;
		return;
	}
	int mid=(l+r)>>1;
	if (nl<=mid) update(nl,nr,l,mid,ls(p));
	if (nr>mid) update(nl,nr,mid+1,r,rs(p));
	push_up(p);
}
int sum(int nl,int nr,int l,int r,int p)
{
	if (nl<=l&&r<=nr) return t[p].sum;
	int mid=(l+r)>>1,ans=0;
	if (nl<=mid) ans+=sum(nl,nr,l,mid,ls(p));
	if (nr>mid) ans+=sum(nl,nr,mid+1,r,rs(p));
	return ans;
}
void cc(int pos,int l,int r,int p,int val)
{
	if (l==r) 
	{
		t[p].sum=val;
		t[p].mn=val;
		t[p].mx=val;
		return;
	}
	int mid=(l+r)>>1;
	if (pos<=mid) cc(pos,l,mid,ls(p),val);
	else cc(pos,mid+1,r,rs(p),val);
	push_up(p);
}
int qmax(int nl,int nr,int l,int r,int p)
{
	if (nl<=l&&r<=nr) return t[p].mx;
	int mid=(l+r)>>1,ans=-INF;
	if (nl<=mid) ans=max(ans,qmax(nl,nr,l,mid,ls(p)));
	if (nr>mid) ans=max(ans,qmax(nl,nr,mid+1,r,rs(p)));
	return ans;
}
int qmin(int nl,int nr,int l,int r,int p)
{
	if (nl<=l&&r<=nr) return t[p].mn;
	int mid=(l+r)>>1,ans=INF;
	if (nl<=mid) ans=min(ans,qmin(nl,nr,l,mid,ls(p)));
	if (nr>mid) ans=min(ans,qmin(nl,nr,mid+1,r,rs(p)));
	return ans;
}

int query_sum(int x,int y)
{
	int ans=0;
	while (top[x]!=top[y])
	{
		if (dep[top[x]]<dep[top[y]]) swap(x,y);
		ans+=sum(id[top[x]],id[x],1,n,1);
		x=fa[top[x]];
	}
	if (dep[x]>dep[y]) swap(x,y);
	ans+=sum(id[x]+1,id[y],1,n,1);
	return ans;
}
int query_min(int x,int y)
{
	int ans=INF;
	while (top[x]!=top[y])
	{
		if (dep[top[x]]<dep[top[y]]) swap(x,y);
		ans=min(ans,qmin(id[top[x]],id[x],1,n,1)); 
		x=fa[top[x]];
	}
	if (dep[x]>dep[y]) swap(x,y);
	ans=min(ans,qmin(id[x]+1,id[y],1,n,1)); 
	return ans;
}
int query_max(int x,int y)
{
	int ans=-INF;
	while (top[x]!=top[y])
	{
		if (dep[top[x]]<dep[top[y]]) swap(x,y);
		ans=max(ans,qmax(id[top[x]],id[x],1,n,1)); 
		x=fa[top[x]];
	}
	if (dep[x]>dep[y]) swap(x,y);
	ans=max(ans,qmax(id[x]+1,id[y],1,n,1)); 
	return ans;
}
void fan(int x,int y) 
{
	while (top[x]!=top[y])
	{
		if (dep[top[x]]<dep[top[y]]) swap(x,y);
		update(id[top[x]],id[x],1,n,1); 
		x=fa[top[x]];
	}
	if (dep[x]>dep[y]) swap(x,y);
	update(id[x]+1,id[y],1,n,1); 
}
void change(int x,int val)
{
	int p=a[x],q=b[x];
	if (dep[p]<dep[q]) swap(p,q);
	cc(id[p],1,n,1,val); 
} 
int main()
{
	freopen("nt2011_travel.in","r",stdin); 
	freopen("nt2011_travel.out","w",stdout); 
	n=read();
	for (int i=1;i<n;i++)
	{
		int x=read()+1,y=read()+1,z=read();
		add_edge(x,y,z);
		a[i]=x;b[i]=y;
	}
	dfs1(1,0,1);
	dfs2(1,1);
	build(1,1,n); 
	m=read();
	for (int i=1;i<=m;i++)
	{
		char s[4];int x,y;
		scanf("%s",s);x=read(),y=read();
		if (s[0]=='S') printf("%d\n",query_sum(x+1,y+1));
		if (s[0]=='C') change(x,y);
		if (s[0]=='N') fan(x+1,y+1);
		if (s[0]=='M'&&s[1]=='I') printf("%d\n",query_min(x+1,y+1));
		if (s[0]=='M'&&s[1]=='A') printf("%d\n",query_max(x+1,y+1));
	}
	return 0;
}