zoukankan      html  css  js  c++  java
  • BZOJ 1180: [CROATIAN2009]OTOCI [LCT]

    1180: [CROATIAN2009]OTOCI

    Time Limit: 50 Sec  Memory Limit: 162 MB
    Submit: 961  Solved: 594
    [Submit][Status][Discuss]

    Description

    给出n个结点以及每个点初始时对应的权值wi。起始时点与点之间没有连边。有3类操作: 1、bridge A B:询问结点A与结点B是否连通。如果是则输出“no”。否则输出“yes”,并且在结点A和结点B之间连一条无向边。 2、penguins A X:将结点A对应的权值wA修改为X。 3、excursion A B:如果结点A和结点B不连通,则输出“impossible”。否则输出结点A到结点B的路径上的点对应的权值的和。给出q个操作,要求在线处理所有操作。数据范围:1<=n<=30000, 1<=q<=300000, 0<=wi<=1000。

    Input

    第一行包含一个整数n(1<=n<=30000),表示节点的数目。第二行包含n个整数,第i个整数表示第i个节点初始时对应的权值。第三行包含一个整数q(1<=n<=300000),表示操作的数目。以下q行,每行包含一个操作,操作的类别见题目描述。任意时刻每个节点对应的权值都是1到1000的整数。

    Output

    输出所有bridge操作和excursion操作对应的输出,每个一行。


    单点修改,链查询.....

    貌似我还没写过splay的单点修改,好像只要修改t[x].w就可以了

    链查询就是M A s得到x到y的链的Splay然后t[y].sum行了

    注意:单点修改后别忘splay一下,这时候Access无所谓

    Access的时候一定要更新,因为重新设置了rc嘛!!!!

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <cmath>
    using namespace std;
    #define pa t[x].fa
    #define lc t[x].ch[0]
    #define rc t[x].ch[1]
    const int N=3e4+5;
    inline int read(){
        char c=getchar();int x=0,f=1;
        while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
        while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
        return x*f;
    }
    struct node{
        int ch[2],fa,rev;
        int sum,w;
    }t[N];
    inline void update(int x){t[x].sum=t[lc].sum+t[rc].sum+t[x].w;}
    inline int wh(int x){return t[pa].ch[1]==x;}
    inline int isRoot(int x){return t[pa].ch[0]!=x&&t[pa].ch[1]!=x;}
    inline void pushDown(int x){
        if(t[x].rev){
            t[lc].rev^=1;
            t[rc].rev^=1;
            swap(lc,rc);
            t[x].rev=0;
        }
    }
    inline void rotate(int x){
        int f=t[x].fa,g=t[f].fa,c=wh(x);
        if(!isRoot(f)) t[g].ch[wh(f)]=x;t[x].fa=g;
        t[f].ch[c]=t[x].ch[c^1];t[t[f].ch[c]].fa=f;
        t[x].ch[c^1]=f;t[f].fa=x;
        update(f);update(x);
    }
    int st[N],top;
    inline void splay(int x){
        top=0;st[++top]=x;
        for(int i=x;!isRoot(i);i=t[i].fa) st[++top]=t[i].fa;
        for(int i=top;i>=1;i--) pushDown(st[i]);
        
        for(;!isRoot(x);rotate(x))
            if(!isRoot(pa)) rotate(wh(x)==wh(pa)?pa:x);
    }
    
    inline void Access(int x){
        for(int y=0;x;y=x,x=pa){
            splay(x);
            rc=y;
            update(x);
        }
    }
    inline void MakeRoot(int x){
        Access(x);
        splay(x);
        t[x].rev^=1;
    }
    inline int FindRoot(int x){
        Access(x);
        splay(x);
        while(lc) x=lc;
        return x;
    }
    inline void Link(int x,int y){
        MakeRoot(x);
        t[x].fa=y;
        splay(x);
    }
    
    int n,Q,x,y;
    char s[N];
    int main(){
        //freopen("in.txt","r",stdin);
        n=read();
        for(int i=1;i<=n;i++) t[i].w=t[i].sum=read();
        Q=read();
        while(Q--){
            scanf("%s",s);x=read();y=read();
            if(s[0]=='b'){
                if(FindRoot(x)==FindRoot(y)) puts("no");
                else puts("yes"),Link(x,y);
            }else if(s[0]=='p'){
                t[x].w=y;
                //Access(x);
                splay(x);
            }else{
                if(FindRoot(x)!=FindRoot(y)) puts("impossible");
                else{
                    MakeRoot(x);Access(y);splay(y);
                    printf("%d
    ",t[y].sum);
                }
            }
        }
    }
  • 相关阅读:
    HTML5 视频(二) <video> 使用 DOM 进行控制
    HTML5 视频(一)
    Front End Developer Questions 前端开发人员问题(三)JavaScript部分
    Front End Developer Questions 前端开发人员问题(二)CSS 后续
    Front End Developer Questions 前端开发人员问题(二)
    Front End Developer Questions 前端开发人员问题(一)
    MySQL学习(二)SQL语句的总结
    MySQL学习(一)MySQLWorkbench(MySQL可视化工具)下载,安装,测试连接,以及注意事项
    my SQL下载安装,环境配置,以及密码忘记的解决,以及navicat for mysql下载,安装,测试连接
    软件工程-构建之法 黄色领骑衫展示
  • 原文地址:https://www.cnblogs.com/candy99/p/6273966.html
Copyright © 2011-2022 走看看