bzoj1036 [ZJOI2008]树的统计Count——LCT

题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1036

LCT水题!

然而没有1A(咬牙)!

注意值有负数,所以取 max 的话要把作为“哨兵”的 0号点 的 max 赋成很小的值才行。

代码如下:

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int const maxn=30005;
int n,m,fa[maxn],c[maxn][3],rev[maxn],mx[maxn],sum[maxn],w[maxn],sta[maxn],a[maxn],b[maxn],top;
bool isroot(int x){return c[fa[x]][0]!=x && c[fa[x]][1]!=x;}
void pushup(int x)
{
    int ls=c[x][0],rs=c[x][1];
    sum[x]=sum[ls]+sum[rs]+w[x];
    mx[x]=x;
    if(w[mx[x]]<w[mx[ls]])mx[x]=mx[ls];
    if(w[mx[x]]<w[mx[rs]])mx[x]=mx[rs];
}
void reverse(int x)
{
    if(rev[x])
    {
        rev[c[x][0]]^=1; rev[c[x][1]]^=1; rev[x]=0;
        swap(c[x][0],c[x][1]);
    }
}
void rotate(int x)
{
    int y=fa[x],z=fa[y],d=(c[y][1]==x);
    if(!isroot(y))c[z][c[z][1]==y]=x;
    fa[x]=z; fa[y]=x; fa[c[x][!d]]=y;
    c[y][d]=c[x][!d]; c[x][!d]=y;
    pushup(y); pushup(x);
}
void splay(int x)
{
    sta[top=1]=x;
    for(int i=x;!isroot(i);i=fa[i])sta[++top]=fa[i];
    for(;top;top--)reverse(sta[top]);
    for(;!isroot(x);rotate(x))
    {
        int y=fa[x],z=fa[y];
        if(isroot(y))continue;
        ((c[y][0]==x)^(c[z][0]==y))?rotate(x):rotate(y);
    }
}
void access(int x)
{
    for(int t=0;x;splay(x),c[x][1]=t,pushup(x),t=x,x=fa[x]);
}
void makeroot(int x)
{
    access(x); splay(x); rev[x]^=1;
}
void link(int x,int y)
{
    makeroot(x); fa[x]=y;
}
void query(int x,int y)
{
    makeroot(x); access(y); splay(y);
}
void cut(int x,int y)
{
    query(x,y); fa[x]=0; c[y][0]=0;
}
void change(int u,int t)
{
    makeroot(u); w[u]=t; pushup(u);//makeroot
}
int main()
{
    scanf("%d",&n); w[mx[0]]=-30005;//!
    for(int i=1,x,y;i<n;i++)scanf("%d%d",&a[i],&b[i]);
    for(int i=1;i<=n;i++)scanf("%d",&w[i]);
    for(int i=1;i<n;i++)link(a[i],b[i]);
    scanf("%d",&m);
    char ch[10];
    for(int i=1,x,y;i<=m;i++)
    {
        scanf("%s",&ch); scanf("%d%d",&x,&y);
        if(ch[0]=='C')change(x,y);
        else
        {
            query(x,y);
            if(ch[1]=='M')printf("%d\n",w[mx[y]]);
            if(ch[1]=='S')printf("%d\n",sum[y]);
        }
    }
    return 0;
}

 

posted @ 2018-06-29 11:50  Zinn  阅读(176)  评论(0编辑  收藏  举报