zoukankan      html  css  js  c++  java
  • [AH/HNOI2017]单旋

    这道题可以用LCT做,开set,LCT,二叉树

    • 操作1:直接开set,找到它要插入的位置,一定是前驱,后缀中deep最大的(显然手玩
    • 操作2:set+LCT询问路径,直接手动提上去,因为树的形态不变
    • 操作3:同2
    • 操作4:LCT::Cut,手动删除
    • 操作5:同4
    • 没了
    • 记得手动更新二叉树(这个一定要想清楚会又WA又TLE又RE n遍

    # include <bits/stdc++.h>
    # define RG register
    # define IL inline
    # define Fill(a, b) memset(a, b, sizeof(a))
    using namespace std;
    typedef long long ll;
    const int _(1e5 + 10);
    
    IL ll Read(){
        char c = '%'; ll x = 0, z = 1;
        for(; c > '9' || c < '0'; c = getchar()) if(c == '-') z = -1;
        for(; c >= '0' && c <= '9'; c = getchar()) x = x * 10 + c - '0';
        return x * z;
    }
    
    int fa[_], ch[2][_], rev[_], S[_], sz[_], qc[_], qx[_], o[_], rt, spc[2][_], spf[_];
    set <int> T;
    set <int> :: iterator it;
    
    IL bool Son(RG int x){  return ch[1][fa[x]] == x;  }
    
    IL bool Isroot(RG int x){  return ch[0][fa[x]] != x && ch[1][fa[x]] != x;  }
    
    IL void Update(RG int x){  sz[x] = sz[ch[0][x]] + sz[ch[1][x]] + 1;  }
    
    IL void Reverse(RG int x){  swap(ch[0][x], ch[1][x]); rev[x] ^= 1;  }
    
    IL void Pushdown(RG int x){  if(!rev[x]) return; Reverse(ch[0][x]); Reverse(ch[1][x]); rev[x] = 0;  }
    
    IL void Rotate(RG int x){
        RG int y = fa[x], z = fa[y], c = Son(x);
        if(!Isroot(y)) ch[Son(y)][z] = x; fa[x] = z;
        ch[c][y] = ch[!c][x]; fa[ch[c][y]] = y;
        ch[!c][x] = y; fa[y] = x;
        Update(y);
    }
    
    IL void Splay(RG int x){
        S[++S[0]] = x;
        for(RG int y = x; !Isroot(y); y = fa[y]) S[++S[0]] = fa[y];
        while(S[0]) Pushdown(S[S[0]--]);
        for(RG int y = fa[x]; !Isroot(x); Rotate(x), y = fa[x])
            if(!Isroot(y)) Son(x) ^ Son(y) ? Rotate(x) : Rotate(y);
        Update(x);
    }
    
    IL void Access(RG int x){  for(RG int y = 0; x; y = x, x = fa[x]) Splay(x), ch[1][x] = y, Update(x);  }
    
    IL int Findroot(RG int x){  Access(x); Splay(x); while(ch[0][x]) x = ch[0][x]; return x;  }
    
    IL void Makeroot(RG int x){  Access(x); Splay(x); Reverse(x);  }
    
    IL void Split(RG int x, RG int y){  Makeroot(x); Access(y); Splay(y);  }
    
    IL void Link(RG int x, RG int y){  if(!x || !y) return; Makeroot(x); fa[x] = y;  }
    
    IL void Cut(RG int x, RG int y){  if(!x || !y) return; Split(x, y); ch[0][y] = fa[x] = 0;  }
    
    IL int Query(RG int x){  Makeroot(rt); Access(x); Splay(x); return sz[x];  }
    
    int main(RG int argc, RG char *argv[]){
        RG int len = 0, m = Read();
        T.insert(-2e9); T.insert(2e9);
        for(RG int i = 1; i <= m; ++i){
            qc[i] = Read();
            if(qc[i] == 1) o[++len] = qx[i] = Read();
        }
        sort(o + 1, o + len + 1);
        for(RG int i = 1; i <= m; ++i)
            if(qc[i] == 1) qx[i] = lower_bound(o + 1, o + len + 1, qx[i]) - o;
        for(RG int i = 1; i <= m; ++i){
            if(qc[i] != 1 && T.size() == 3){
                puts("1"); it = T.begin(); ++it;
                if(qc[i] >= 3) T.erase(it), rt = 0;
                continue;
            }
            if(qc[i] == 1){
                if(T.size() == 2){  T.insert(qx[i]); rt = qx[i]; puts("1"); continue;  }
                it = T.lower_bound(qx[i]); RG int ans = 0, pos, g;
                if(*it != 2e9){  g = Query(*it); if(g > ans) ans = g, pos = *it;  }
                if(*(--it) != -2e9){  g = Query(*it); if(g > ans) ans = g, pos = *it;  }
                T.insert(qx[i]); Link(qx[i], pos);
                spc[qx[i] > pos][pos] = qx[i]; spf[qx[i]] = pos;
                printf("%d
    ", ans + 1);
            }
            else if(qc[i] == 2){
                it = T.begin(); ++it;
                RG int x = *it, y = spc[1][x], z = spf[x];
                printf("%d
    ", Query(x));
                if(rt != x){
                    Cut(x, z); Cut(x, y); Link(x, rt); Link(y, z);
                    spf[rt] = x; spf[x] = 0; spf[y] = z; spc[1][x] = rt; rt = x; spc[0][z] = y;
                }
            }
            else if(qc[i] == 3){
                it = T.end(); --it; --it;
                RG int x = *it, y = spc[0][x], z = spf[x];
                printf("%d
    ", Query(x));
                if(rt != x){
                    Cut(x, z); Cut(x, y); Link(x, rt); Link(y, z);
                    spf[rt] = x; spf[x] = 0; spf[y] = z; spc[0][x] = rt; rt = x; spc[1][z] = y;
                }
            }
            else if(qc[i] == 4){
                it = T.begin(); ++it;
                RG int x = *it, y = spc[1][x], z = spf[x];
                T.erase(it);
                printf("%d
    ", Query(x));
                Cut(x, z); Cut(x, y); Link(y, z);
                spf[y] = z; spc[0][x] = spc[1][x] = spf[x] = 0; spc[0][z] = y;
                if(rt == x) rt = y;
            }
            else if(qc[i] == 5){
                it = T.end(); --it; --it;
                RG int x = *it, y = spc[0][x], z = spf[x];
                T.erase(it);
                printf("%d
    ", Query(x));
                Cut(x, z); Cut(x, y); Link(y, z);
                spf[y] = z; spc[0][x] = spc[1][x] = spf[x] = 0; spc[1][z] = y;
                if(rt == x) rt = y;
            }
        }
        return 0;
    }
    
  • 相关阅读:
    Aurora 数据库支持多达五个跨区域只读副本
    Amazon RDS 的 Oracle 只读副本
    Amazon EC2 密钥对
    DynamoDB 读取请求单位和写入请求单位
    使用 EBS 优化的实例或 10 Gb 网络实例
    启动 LAMP 堆栈 Web 应用程序
    AWS 中的错误重试和指数退避 Error Retries and Exponential Backoff in AWS
    使用 Amazon S3 阻止公有访问
    路由表 Router Table
    使用MySQLAdmin工具查看QPS
  • 原文地址:https://www.cnblogs.com/cjoieryl/p/8206339.html
Copyright © 2011-2022 走看看