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;
    }
  • 相关阅读:
    Android “swipe” vs “fling”
    Parcel
    ViewConfiguration 和 ViewConfigurationCompat
    Hive记录-配置支持事务管理hive-site.xml
    SQL记录-资源正忙online或nowait
    SQL记录-解锁和dbms_job操作
    Java记录-SpringMVC整合Echarts画地图加散点图
    Hive记录-impala常用命令
    Hive记录-Sqoop常用命令
    Linux记录-shell一行代码杀死进程(收藏)
  • 原文地址:https://www.cnblogs.com/Zinn/p/9244087.html
Copyright © 2011-2022 走看看