刚学树剖,求差错 || P2590
  • 板块学术版
  • 楼主MoFalkMusic
  • 当前回复2
  • 已保存回复2
  • 发布时间2020/7/16 09:54
  • 上次更新2023/11/6 23:02:53
查看原帖
刚学树剖,求差错 || P2590
358108
MoFalkMusic楼主2020/7/16 09:54
#include<bits/stdc++.h>
#define root tree[k]
#define ls tree[k<<1]
#define rs tree[k<<1|1]
#define mid root.l+(root.r-root.l)/2 
#define inf 0x3f3f3f3f
using namespace std;
struct edge
{
	int nx,to;
}e[200000];
struct pot
{
	int l,r,max,sum,tag;
}tree[200000];
int n,m,r,p,cnt,x,y,q,tot,
fa[200000],dep[200000],siz[200000],son[200000],dfn[200000],rk[200000],head[200000],top[200000],dis[200000];
string st;
void ad(int x,int y)
{
    tot++;
	e[tot].to=y;
	e[tot].nx=head[x];
	head[x]=tot; 
}
void dfs(int k,int ft)
{
	fa[k]=ft;dep[k]=dep[ft]+1;siz[k]=1;son[k]=0;
	for (int i=head[k];i;i=e[i].nx)
		if (e[i].to!=ft)
	{
		  dfs(e[i].to,k);  
		siz[k]+=siz[e[i].to];
		if (siz[e[i].to]>siz[son[k]]) son[k]=e[i].to;
	}
}
void dfs1(int k,int rt)
{
	dfn[k]=++cnt;
	rk[cnt]=k;
	top[k]=rt;
	if (son[k]) dfs1(son[k],rt);
	for (int i=head[k];i;i=e[i].nx)
	if (e[i].to!=fa[k])
	{
		if (e[i].to==rt||e[i].to==son[k]) continue;
		dfs1(e[i].to,e[i].to);
	}
}
void push_down(int k)
{
	if (root.tag==inf) return;
	ls.max=rs.max=root.tag;
	ls.sum=root.tag*(ls.r-ls.l+1);
	rs.sum=root.tag*(rs.r-rs.l+1);
	ls.tag=rs.tag=root.tag;
	root.tag=inf;
}
void push_up(int k)
{
	root.max=max(ls.max,rs.max);
	root.sum=ls.sum+rs.sum;
}
void build(int k,int l,int r)
{
	root.l=l,root.r=r,root.tag=inf;
	if (l==r) root.max=root.sum=dis[rk[l]];
	else
	{
		build(k<<1,l,l+(r-l)/2);
		build(k<<1|1,l+(r-l)/2+1,r);
		push_up(k);
	}
}
void modify(int k,int l,int r,int val)
{
	if (root.l==l&&root.r==r)
	{
	  root.max=val;
	  root.sum=val*(r-l+1);
	  root.tag=val;
	  return;
    }
    push_down(k);
    if (l<=mid) modify(k<<1,l,min(r,mid),val);
    if (r>mid) modify(k<<1|1,max(l,mid+1),r,val);
    push_up(k);
}
int querymx(int k,int l,int r)
{
	if (l>r) return -inf;
	if (root.l==l&&root.r==r)
	{
	  return root.max;
    }
    int ans=-inf;
    push_down(k);
    if (l<=mid) ans=max(ans,querymx(k<<1,l,min(r,mid)));
    if (r>mid) ans=max(ans,querymx(k<<1|1,max(l,mid+1),r));
    push_up(k);
    return ans;
}
int querysum(int k,int l,int r)
{
	if (root.l==l&&root.r==r)
	{
	  return root.sum;
    }
    int ans=0;
    push_down(k);
    if (l<=mid) ans+=querysum(k<<1,l,min(r,mid));
    if (r>mid) ans+=querysum(k<<1|1,max(l,mid+1),r);
    push_up(k);
    return ans;
}
void Modify(int x,int y,int val)
{
	while (top[x]!=top[y])
	{
		if (!dep[top[x]]<dep[top[y]]) swap(x,y);
		modify(1,dfn[x],dfn[top[x]],val);
		x=fa[top[x]];
    }
    if (dep[x]>dep[y]) swap(x,y);
    modify(1,dfn[x],dfn[y],val);
}
int Querymax(int x,int y)
{
	int sum=-inf;
	while (top[x]!=top[y])
	{
		if (!dep[top[x]]<dep[top[y]]) swap(x,y);
		sum=max(sum,querymx(1,dfn[x],dfn[top[x]]));
		x=fa[top[x]];
    }
    if (dep[x]>dep[y]) swap(x,y);
    sum=max(sum,querymx(1,dfn[x],dfn[y]));
    return sum;
}
int Querysum(int x,int y)
{
	int sum=0;
	while (top[x]!=top[y])
	{
		if (!dep[top[x]]<dep[top[y]]) swap(x,y);
		sum+=querysum(1,dfn[x],dfn[top[x]]);
		x=fa[top[x]];
    }
    if (dep[x]>dep[y]) swap(x,y);
    sum+=querysum(1,dfn[x],dfn[y]);
    return sum;
}
int main()
{
	cin>>n;
	for (int i=1;i<n;i++)
	{
		cin>>x>>y;
		ad(x,y);
		ad(y,x);
	}
	dfs(1,0);
	dfs1(1,1);
	for (int i=1;i<=n;i++) cin>>dis[i];
	build(1,1,n);
	cin>>q;
	for (int i=1;i<=q;i++)
	{
		cin>>st;
		cin>>x>>y;
		if (st=="CHANGE") Modify(x,x,y);
		else if (st=="QMAX") cout<<Querymax(x,y);
		else cout<<Querysum(x,y);
	}
}
2020/7/16 09:54
加载中...