Description
一棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w。
我们将以下面的形式来要求你对这棵树完成一些操作:
I. CHANGE u t : 把结点u的权值改为t
II. QMAX u v: 询问从点u到点v的路径上的节点的最大权值
III. QSUM u v: 询问从点u到点v的路径上的节点的权值和
注意:从点u到点v的路径上的节点包括u和v本身
Solution
链剖裸题。。。。。。
Code
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cmath>
#define fo(i,a,b) for(i=a;i<=b;i++)
#define fod(i,a,b) for(i=a;i>=b;i--)
using namespace std;
struct note
{
int l,r,sum,mx,ls,rs;
};
struct nt1
{
int x,y;
};
note tree[100001];
int top[30001],deep[30001],size[30001],pt[30001],dfn[30001],ft[30001],son[30001],a[30001],lazy[100001];
nt1 a1[60001];
int a2[30001][2];
int n,m,dfm;
bool cmp(nt1 x,nt1 y)
{
return x.x<y.x;
}
void give(int f,int k)
{
tree[k].mx=lazy[f];
tree[k].sum=(tree[k].r-tree[k].l+1)*lazy[f];
}
void newptl(int f,int l,int r)
{
if (tree[f].ls==0)
{
tree[f].ls=++m;
tree[m].l=l;
tree[m].r=r;
}
}
void newptr(int f,int l,int r)
{
if (tree[f].rs==0)
{
tree[f].rs=++m;
tree[m].l=l;
tree[m].r=r;
}
}
void find(int now,int l,int r,int &sm,int &ma)
{
if (tree[now].l==l&&tree[now].r==r)
{
sm=tree[now].sum;
ma=tree[now].mx;
return;
}
int ls=tree[now].ls,rs=tree[now].rs;
if (lazy[now]!=1802201963)
{
if (ls!=0) give(now,ls);
if (rs!=0) give(now,rs);
lazy[now]=1802201963;
}
int mid=(tree[now].l+tree[now].r)/2;
if (r<=mid) find(ls,l,r,sm,ma);
else if(l>mid) find(rs,l,r,sm,ma);
else
{
int s1,m1;
find(ls,l,mid,sm,ma);
find(rs,mid+1,r,s1,m1);
sm+=s1;
ma=max(ma,m1);
}
tree[now].sum=tree[tree[now].ls].sum+tree[tree[now].rs].sum;
tree[now].mx=max(tree[tree[now].ls].mx,tree[tree[now].rs].mx);
}
void ask(int u,int v,int &sm,int &ma,bool uh,bool vh)
{
int s1=0,m1=-1802201963,s2=0,m2=-1802201963;
if (u==v)
{
if (uh==0&&vh==0)
{
find(1,dfn[u],dfn[v],s1,m1);
sm=s1;
ma=m1;
return;
}
sm=0;
ma=-1802201963;
return;
}
int f1=top[u],f2=top[v];
if (f1==f2)
{
if (deep[u]>deep[v]) swap(u,v);
find(1,dfn[u],dfn[v],sm,ma);
return;
}
else
{
if (deep[f1]<deep[f2])
{
swap(u,v);
swap(f1,f2);
swap(uh,vh);
}
find(1,dfn[f1],dfn[u],s1,m1);
if (ft[f1]==f1) ask(ft[f1],v,s2,m2,1,vh);
else ask(ft[f1],v,s2,m2,0,vh);
sm=s1+s2;
ma=max(m1,m2);
}
}
void change(int now,int l,int r,int dt)
{
if (tree[now].l==l&&tree[now].r==r)
{
tree[now].mx=dt;
tree[now].sum=(r-l+1)*dt;
lazy[now]=dt;
return;
}
int ls=tree[now].ls,rs=tree[now].rs;
int mid=(tree[now].l+tree[now].r)/2;
if (lazy[now]!=1802201963)
{
if (ls!=0) give(now,ls);
if (rs!=0) give(now,rs);
lazy[now]=1802201963;
}
if (r<=mid)
{
newptl(now,tree[now].l,mid);
change(tree[now].ls,l,r,dt);
}
else if(l>mid)
{
newptr(now,mid+1,tree[now].r);
change(tree[now].rs,l,r,dt);
}
else
{
newptl(now,tree[now].l,mid);
newptr(now,mid+1,tree[now].r);
change(tree[now].ls,l,mid,dt);
change(tree[now].rs,mid+1,r,dt);
}
tree[now].sum=tree[tree[now].ls].sum+tree[tree[now].rs].sum;
tree[now].mx=max(tree[tree[now].ls].mx,tree[tree[now].rs].mx);
}
void dfs1(int k,int f,int dep)
{
int i,sz=0,sn=0,wsn=0;
fo(i,a2[k][0],a2[k][1])
{
int p=a1[i].y;
if (p!=f)
{
ft[p]=k;
dfs1(p,k,dep+1);
sz+=size[p];
if (size[p]>sn)
{
sn=size[p];
wsn=p;
}
}
}
size[k]=sz+1;
son[k]=wsn;
deep[k]=dep;
}
void dfs2(int k,int f)
{
dfn[k]=++dfm;
change(1,dfn[k],dfn[k],a[k]);
int i;
if (son[k]!=0)
{
top[son[k]]=top[k];
dfs2(son[k],k);
}
fo(i,a2[k][0],a2[k][1])
{
int p=a1[i].y;
if (p!=f&&p!=son[k])
{
top[p]=p;
dfs2(p,k);
}
}
}
int main()
{
cin>>n;
int i,j,s1,m1;
fo(i,1,n-1)
{
scanf("%d%d",&a1[2*i-1].x,&a1[2*i-1].y);
a1[2*i].x=a1[2*i-1].y;
a1[2*i].y=a1[2*i-1].x;
}
sort(a1+1,a1+2*n-1,cmp);
fo(i,1,2*n-2)
{
if (a1[i].x!=a1[i-1].x)
{
a2[a1[i].x][0]=i;
a2[a1[i-1].x][1]=i-1;
}
}
a2[a1[2*n-2].x][1]=2*n-2;
fo(i,1,n) scanf("%d",&a[i]);
memset(lazy,107,sizeof(lazy));
dfs1(1,0,1);
dfm=0;
top[1]=1;
m=1;
tree[1].l=1;
tree[1].r=n;
dfs2(1,0);
ft[1]=1;
scanf("\n");
int cz;
scanf("%d",&cz);
scanf("\n");
int ct=0;
fo(i,1,cz)
{
char c,c1;
scanf("%c%c",&c,&c1);
if (c=='C')
{
int x,t;
scanf("ANGE %d%d\n",&x,&t);
change(1,dfn[x],dfn[x],t);
}
else
{
int su,ma,u,v;
if (c1=='M') scanf("AX %d%d\n",&u,&v);
else scanf("UM %d%d\n",&u,&v);
if (u==v) find(1,dfn[u],dfn[v],su,ma);
else ask(u,v,su,ma,0,0);
if (c1=='M') printf("%d\n",ma);
else printf("%d\n",su);
}
}
}