zoukankan      html  css  js  c++  java
  • BZOJ_1180_[CROATIAN2009]OTOCI_LCT

    BZOJ_1180_[CROATIAN2009]OTOCI_LCT

    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操作对应的输出,每个一行。

    Sample Input

    5
    4 2 4 5 6
    10
    excursion 1 1
    excursion 1 2
    bridge 1 2
    excursion 1 2
    bridge 3 4
    bridge 3 5
    excursion 4 5
    bridge 1 3
    excursion 2 4
    excursion 2 5

    Sample Output

    4
    impossible
    yes
    6
    yes
    yes
    15
    yes
    15
    16

     LCT维护点权和,支持单点修改。
    注意bridge操作是连通输出‘no'
     
    代码:
    #include <stdio.h>
    #include <string.h>
    #include <algorithm>
    using namespace std;
    #define N 30050
    #define ls ch[p][0]
    #define rs ch[p][1]
    #define get(x) (ch[f[x]][1]==x)
    int ch[N][2],f[N],rev[N],sum[N],val[N],n,m;
    char opt[20];
    inline bool isrt(int p) {
        return ch[f[p]][0]!=p&&ch[f[p]][1]!=p;
    }
    inline void pushdown(int p) {
        if(rev[p]) {
            swap(ch[ls][0],ch[ls][1]); swap(ch[rs][0],ch[rs][1]);
            rev[ls]^=1; rev[rs]^=1; rev[p]=0;
        }
    }
    inline void pushup(int p) {
        sum[p]=sum[ls]+sum[rs]+val[p];
    }
    void update(int p) {
        if(!isrt(p)) update(f[p]);
        pushdown(p);
    }
    void rotate(int x) {
        int y=f[x],z=f[y],k=get(x);
        if(!isrt(y)) ch[z][ch[z][1]==y]=x;
        ch[y][k]=ch[x][!k]; f[ch[y][k]]=y;
        ch[x][!k]=y; f[y]=x; f[x]=z;
        pushup(y); pushup(x);
    }
    void splay(int x) {
        update(x);
        for(int fa;fa=f[x],!isrt(x);rotate(x))
            if(!isrt(fa))
                rotate(get(fa)==get(x)?fa:x);
    }
    void access(int p) {
        int t=0;
        while(p) splay(p),rs=t,pushup(p),t=p,p=f[p];
    }
    void makeroot(int p) {
        access(p); splay(p); swap(ls,rs); rev[p]^=1;
    }
    void link(int x,int p) {
        makeroot(x); splay(p); f[x]=p;
    }
    void cut(int x,int p) {
        makeroot(x); access(p); splay(p); ls=f[x]=0;
    }
    int find(int p) {
        access(p); splay(p);
        while(ls) pushdown(p),p=ls;
        return p;
    }
    void fix(int p,int v) {
        access(p); splay(p); val[p]=v; pushup(p);
    }
    int main() {
        scanf("%d",&n);
        int i,x,y;
        for(i=1;i<=n;i++) scanf("%d",&val[i]);
        scanf("%d",&m);
        for(i=1;i<=m;i++) {
            scanf("%s%d%d",opt,&x,&y);
            if(opt[0]=='e') {
                int t1=find(x),t2=find(y);
                if(t1!=t2) {
                    puts("impossible");
                }
                else {
                    makeroot(x); access(y); splay(y);
                    printf("%d
    ",sum[y]);
                }
            }else if(opt[0]=='b') {
                int t1=find(x),t2=find(y);
                if(t1==t2) puts("no");
                else {
                    puts("yes"); link(x,y);
                }
            }else {
                fix(x,y);
            }
        }
    }
    
  • 相关阅读:
    ThreadLocal内存泄漏真因探究(转)
    JAVA设计模式工厂模式
    java设计模式单例模式
    Java-Socket
    Java-Queue总结
    Java-Reentrantlock
    Java-Iterator遍历集合
    安装和启动docker
    C# System.Reflection.Assembly动态加载资源文件
    C#调用 kernel32.dll
  • 原文地址:https://www.cnblogs.com/suika/p/8967917.html
Copyright © 2011-2022 走看看