萌 新 求 助( 会 关 注 的 )
查看原帖
萌 新 求 助( 会 关 注 的 )
91956
Dreamweaver楼主2021/4/17 10:22
#include<bits/stdc++.h>
using namespace std;
#define mod 1000007
#define inf 0x3f3f3f
#define re register
#define maxn 100000
#define ll long long
#define ls(a)	a<<1
#define rs(a)	a<<1|1 
int n,q;
int w[30030],size[30030],wt[30030],id[30030],son[30030],fa[30030],dep[30030],top[30030];
struct node
{
	int l,r,sum,mx,tag;
	node()
	{
		sum=mx=tag=0;
	}
}z[200010];
struct Edge
{
	int s,t,next;
}edge[100010];
int head[30030],cnt,t;
void add(int s,int t)
{
	edge[++cnt].s=s;
	edge[cnt].t=t;
	edge[cnt].next=head[s];
	head[s]=cnt;
}
void dfs1(int u,int ff)
{
	dep[u]=dep[ff]+1;
	fa[u]=ff;
	size[u]=1;
	int ms=-1;
	for(re int i=head[u];i;i=edge[i].next)
	{
		int tt=edge[i].t;
		if(tt==ff)	continue;
		dfs1(tt,u);
		size[u]+=size[tt];
		if(size[tt]>ms)	son[u]=tt,ms=size[tt];
	}
}
void dfs2(int u,int rt)
{
	id[u]=++t;
	wt[t]=w[u];
	top[u]=rt;
	if(son[u])	dfs2(son[u],rt);
	for(re int i=head[u];i;i=edge[i].next)
	{
		int tt=edge[i].t;
		if(tt==fa[u]||tt==son[u])	continue;
		dfs2(tt,tt);
	}
}

void pushup(int rt)
{
	z[rt].mx=max(z[ls(rt)].mx,z[rs(rt)].mx);////// ?????
	z[rt].sum=(z[ls(rt)].sum+z[rs(rt)].sum);
}
void build(int l,int r,int rt)
{
	z[rt].l=l;
	z[rt].r=r;
	if(l==r)
	{
		z[rt].sum=z[rt].mx=wt[l];
		return ;
	}
	int m=l+r>>1;
	build(l,m,ls(rt));
	build(m+1,r,rs(rt));
	pushup(rt);
}
/*
void f(int rt,int k)
{
	z[rt].tag+=k;
	z[rt].sum+=(z[rt].r-z[rt].l+1)*k;
	z[rt].mx+=k;
}
void pushdown(int rt)
{
//	if(z[rt].tag==(-123))	return ;
	f(ls(rt),z[rt].tag);
	f(rs(rt),z[rt].tag);
	//z[rt].tag=-123;
	z[rt].tag=0;
}
void modify(int l,int r,int k,int rt)
{
	if(l<=z[rt].l&&z[rt].r<=r)
	{
		z[rt].tag+=k;
		z[rt].sum+=(z[rt].r-z[rt].l+1)*k;
		z[rt].mx+=k;
		return ;
	}
	pushdown(rt);
	int m=z[rt].l+z[rt].r>>1;
	if(l<=m)	modify(l,r,k,ls(rt));
	if(m<r)	modify(l,r,k,rs(rt));
	pushup(rt);
	return ;
}*/
void change(int rt,int k,int pos)
{
	if(pos>z[rt].r||pos<z[rt].l) return ;
	if(z[rt].l==z[rt].r&&z[rt].r==pos)
	{
		z[rt].sum=k;
		z[rt].mx=k;
		return ;
	}
	int mid=z[rt].l+z[rt].r>>1;
	if(mid>=pos) change(rt<<1,k,pos);
	if(mid+1<=pos) change((rt<<1)+1,k,pos);
	pushup(rt);
}
int querys(int l,int r,int rt)
{
	int ans=0;
	if(l<=z[rt].l&&z[rt].r<=r)	return z[rt].sum;
	pushdown(rt);
	int m=z[rt].l+z[rt].r>>1;
	if(l<=m)	ans+=querys(l,r,ls(rt));
	if(m<r)	ans+=querys(l,r,rs(rt));
	return ans;
}
int querym(int l,int r,int rt)
{
	int ans=-99999999;
	if(l<=z[rt].l&&z[rt].r<=r)	return z[rt].mx;
	pushdown(rt);
	int m=z[rt].l+z[rt].r>>1;
	if(l<=m)	ans=max(ans,querym(l,r,ls(rt)));
	if(m<r)	ans=max(ans,querym(l,r,rs(rt)));
	return ans;
}
int lists(int x,int y)
{
	int ans=0;
	
	while(top[x]!=top[y])
	{
		if(dep[top[x]]<dep[top[y]])	swap(x,y);
		ans+=querys(id[top[x]],id[x],1);
		x=fa[top[x]];
	}
	if(dep[x]>dep[y])	swap(x,y);
	ans+=querys(id[x],id[y],1);
	return ans;
}
int listm(int x,int y)
{
	int ans=-99999999;
	while(top[x]!=top[y])
	{
		if(dep[top[x]]<dep[top[y]])	swap(x,y);
		ans=max(ans,querym(id[top[x]],id[x],1));
		x=fa[top[x]];
	}
	if(dep[x]>dep[y])	swap(x,y);
	ans=max(ans,querym(id[x],id[y],1));
	return ans;
}
inline 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<<3)+(x<<1)+ch-'0'; ch=getchar();}
    return x*f;
}
int main()
{
//	freopen("a.in","r",stdin);
//	freopen("a.out","w",stdout);
//	printf("%dM\n",(sizeof(dp) >> 20));
	cin>>n;
	for(re int i=1;i<n;i++)
	{
		int a,b;
		a=read(),b=read();
		add(a,b),add(b,a);
	}
	for(re int i=1;i<=n;i++)	w[i]=read();
	dfs1(1,0);
	dfs2(1,1);
	cin>>q;
	for(re int i=1;i<=q;i++)
	{
		string op;
		int a,b;
		cin>>op;
		a=read(),b=read();
		if(op[0]=='C')
		{
		//	int o=querys(id[a],id[a],1);			
		//	modify(id[a],id[a],b-o,1);
			change(1,b,id[a]);
			continue;
		}
		if(op[1]=='M')
		{
			cout<<listm(a,b)<<'\n';
			continue;
		}
		if(op[1]=='S')
		{
			cout<<lists(a,b)<<'\n';
			continue;
		}
	}
	return 0;
}

求助树剖入门题

2021/4/17 10:22
加载中...