• [洛谷1383]高级打字机 题解


    题解
    这道题一看就珂以用主席树啊
    这是一道神奇的题目,那么我们先敲一个主席树,然后维护一个数组len,表示下一次应该在len + 1插入,
    之后对于T操作,在上一个版本的len + 1上直接执行插入
    对于Q操作,直接查询
    对于U操作,直接找到对应版本复制即可

    rt[rt_num] = rt[((rt_num - num - 1) > 0 ? (rt_num - num - 1) : 0)];
    ls[rt_num] = ls[((rt_num - num - 1) > 0 ? (rt_num - num - 1) : 0)], rs[rt_num] = rs[((rt_num - num - 1) > 0 ? (rt_num - num - 1) : 0)];
    len[rt_num] = len[rt_num - num - 1];
    

    代码

    #include <cstdio>
    #include <iostream>
    #define ll long long
    
    using namespace std;
    
    ll read(){
        ll x = 0; int zf = 1; char ch = ' ';
        while (ch != '-' && (ch < '0' || ch > '9')) ch = getchar();
        if (ch == '-') zf = -1, ch = getchar();
        while (ch >= '0' && ch <= '9') x = x * 10 + ch - '0', ch = getchar(); return x * zf;
    }
    
    int s[20000005];
    int ls[20000005], rs[20000005];
    int len[20000005];
    int rt[20000005], pre[20000005];
    int tot;
    
    inline void a(int pos){
        s[pos] = s[ls[pos]] + s[rs[pos]];
    }
    
    inline int getNew(){
        return (++tot);
    }
    
    void build(int pos, int l, int r){
        if (l == r){
            if (pos > tot)
                tot = pos;
            s[pos] = 0;
            return ;
        }
        int mid = (l + r) >> 1;
        ls[pos] = pos << 1, rs[pos] = (pos << 1) + 1;
        build(pos << 1, l, mid);
        build((pos << 1) + 1, mid + 1, r);
        a(pos);
    }
    
    int query(int pos, int l, int r, int k){
        if (l == r)
            return s[pos];
        int mid = (l + r) >> 1;
        if (k <= mid)
            return query(ls[pos], l, mid, k);
        else
            return query(rs[pos], mid + 1, r, k);
    }
    
    void add(int pos, int pre, int l, int r, int k, int val){
        if (l == r){
            s[pos] = val;
            return ;
        }
        int mid = (l + r) >> 1;
        if (k <= mid){
            rs[pos] = rs[pre]; ls[pos] = getNew();
            add(ls[pos], ls[pre], l, mid, k, val);
        }
        else{
            ls[pos] = ls[pre]; rs[pos] = getNew();
            add(rs[pos], rs[pre], mid + 1, r, k, val);
        }
        a(pos);
    }
    
    int main(){
        freopen("type.in", "r", stdin);
        freopen("type.out", "w", stdout);
        int q;
        q = read();
        rt[0] = 1, len[0] = 0;
        build(rt[0], 1, 100000);
        char op; int num; int rt_num = 0;
        for (int i = 1; i <= q; ++i){
            cin >> op;
            if (op == 'T'){
                char c; cin >> c;
                rt[++rt_num] = getNew();
                len[rt_num] = len[rt_num - 1] + 1;
                add(rt[rt_num], rt[rt_num - 1], 1, 100000, len[rt_num], (int)(c));
            }
            else if (op == 'Q'){
                num = read();
                printf("%c
    ", (char)(query(rt[rt_num], 1, 100000, num)));
            }
            else if (op == 'U'){
                num = read(), ++rt_num;
                rt[rt_num] = rt[((rt_num - num - 1) > 0 ? (rt_num - num - 1) : 0)];
                ls[rt_num] = ls[((rt_num - num - 1) > 0 ? (rt_num - num - 1) : 0)], rs[rt_num] = rs[((rt_num - num - 1) > 0 ? (rt_num - num - 1) : 0)];
                len[rt_num] = len[rt_num - num - 1];
            }
        }
        fclose(stdin);
        fclose(stdout);
        return 0;
    }
    
  • 相关阅读:
    第五次站立会议
    第四次站立会议
    第三次晚间站立总结会议
    易校小程序典型用户需求分析
    第三次站立会议
    第二次晚间站立总结会议
    第二次站立会议
    第一次晚间站立总结会议
    MyBatis注解
    延迟加载与缓存
  • 原文地址:https://www.cnblogs.com/linzhengmin/p/10925395.html
Copyright © 2020-2023  润新知