zoukankan      html  css  js  c++  java
  • 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
    ",w[mx[y]]);
                if(ch[1]=='S')printf("%d
    ",sum[y]);
            }
        }
        return 0;
    }
  • 相关阅读:
    SD卡测试
    测试人员可能会遇到的问题
    HDU 1024 Max Sum Plus Plus
    HDU 1176 免费馅饼
    HDU 1257 最少拦截系统
    HDU 1087 Super Jumping! Jumping! Jumping!
    poj 1328 Radar Installation
    poj 1753 Flip Game
    HDU 1003 Max Sum
    HDU 5592 ZYB's Premutation(BestCoder Round #65 C)
  • 原文地址:https://www.cnblogs.com/Zinn/p/9242732.html
Copyright © 2011-2022 走看看