zoukankan      html  css  js  c++  java
  • bzoj2157 旅游——LCT

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

    仍然是LCT模板题~

    不过有一些需要注意的地方,点和边的区分,0号点的 mx 和 mn 等等;

    还有变成相反数的处理,要像线段树一样先修改再下传标记,那么查询时候就不用先 pushdown 了;

    不过1A还是极好的~

    代码如下:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    using namespace std;
    int const maxn=40005,inf=1005;
    int n,m,fa[maxn],mx[maxn],mn[maxn],sum[maxn],w[maxn],c[maxn][3],rev[maxn],tag[maxn],sta[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]=max(mx[ls],mx[rs]); mn[x]=min(mn[ls],mn[rs]);
        if(x<=n)return;
        mx[x]=max(mx[x],w[x]); mn[x]=min(mn[x],w[x]);
    }
    void tg(int x)
    {
        tag[x]^=1;
        w[x]=-w[x]; sum[x]=-sum[x]; 
        swap(mx[x],mn[x]); mx[x]=-mx[x]; mn[x]=-mn[x];
    }
    void pushdown(int x)
    {
        int ls=c[x][0],rs=c[x][1];
        if(rev[x])
        {
            rev[ls]^=1; rev[rs]^=1; rev[x]=0;
            swap(c[x][0],c[x][1]);
        }
        if(tag[x])
        {
            tag[x]=0; 
            if(ls)tg(ls); if(rs)tg(rs);//
        }
    }
    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--)pushdown(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;c[x][1]=t,pushup(x),t=x,x=fa[x])splay(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 change(int x,int t)
    {
        makeroot(x); w[x]=t; pushup(x);
    }
    int main()
    {
        scanf("%d",&n);
        mx[0]=-inf; mn[0]=inf;//
        for(int i=1,x,y,z;i<n;i++)
        {
            scanf("%d%d%d",&x,&y,&z); x++; y++;
            w[i+n]=z;
            link(x,i+n); link(y,i+n);
        }
        scanf("%d",&m); char ch[10];
        for(int i=1,x,y;i<=m;i++)
        {
            scanf("%s%d%d",&ch,&x,&y);
            if(ch[0]=='C')change(x+n,y);
            else
            {
                x++; y++; query(x,y);
                if(ch[0]=='N')tg(y);
                if(ch[0]=='S')printf("%d
    ",sum[y]);
                if(ch[1]=='A')printf("%d
    ",mx[y]);
                if(ch[1]=='I')printf("%d
    ",mn[y]);
            }
        }
        return 0;
    }
  • 相关阅读:
    【SAS NOTE】OUTPUT
    【SAS NOTES】_NULL_
    【SAS NOTE】sas 9.2 安装
    【SAS NOTE】FREQ
    纯数学教程 Page 203 例XLI (1)
    纯数学教程 Page 203 例XLI (3)
    纯数学教程 Page 203 例XLI (2)
    Prove Cauchy's inequality by induction
    纯数学教程 Page 325 例LXVIII (15) 调和级数发散
    纯数学教程 Page 325 例LXVIII (15) 调和级数发散
  • 原文地址:https://www.cnblogs.com/Zinn/p/9244087.html
Copyright © 2011-2022 走看看