zoukankan      html  css  js  c++  java
  • gym 101064 G.The Declaration of Independence (主席树)

    题目链接:

    题意:

    n个操作,有两种操作:

    E p  c    在序号为p的队列尾部插入c得到新的队列,序号为i

    D p   查询并删除序号为p的队列顶部的元素,得到序号为i的新队列

    思路:

    需要查询历史版本,我们可以用将这些操作都更新在主席树上,这两个操作可以等价为更新一个点,查询一个点,尾部和顶部的元素我们可以分别用l[i],r[i]来维护第i个队列的顶部元素和尾部元素,查询的时候直接在主席树上找就好了。

    实现代码:

    #include<iostream>
    #include<cstdio>
    using namespace std;
    #define lson l,m,rt<<1
    #define rson m+1,r,rt<<1|1
    #define mid int m = (l + r) >> 1
    const int M = 1e5+10;
    int ls[M*40],rs[M*40],sum[M*40],idx,root[M];
    void update(int old,int &rt,int p,int c,int l,int r){
        rt = ++idx; ls[rt] = ls[old]; rs[rt] = rs[old];
        sum[rt] = sum[old];
        if(l == r){
            sum[rt] = c;
            return ;
        }
        mid;
        if(p <= m) update(ls[old],ls[rt],p,c,l,m);
        else update(rs[old],rs[rt],p,c,m+1,r);
    }
    
    int query(int p,int l,int r,int rt){
        if(l == r) return sum[rt];
        mid;
        if(p <= m) return query(p,l,m,ls[rt]);
        else return query(p,m+1,r,rs[rt]);
    }
    int n,p,c;
    char op[5];
    int l[M],r[M];
    int main()
    {
        idx = 0; l[0] = 1;r [0] = 0;
        scanf("%d",&n);
        for(int i = 1;i <= n;i ++){
            scanf("%s",op);
            if(op[0] == 'E'){
                scanf("%d%d",&p,&c);
                l[i] = l[p]; r[i] = r[p];
                update(root[p],root[i],++r[i],c,1,n);
            }
            else {
                scanf("%d",&p);
                l[i] = l[p]; r[i] = r[p]; root[i] = root[p];
                printf("%d
    ",query(l[i]++,1,n,root[i]));
            }
        }
        return 0;
    }
  • 相关阅读:
    Spring Boot之发送HTTP请求(RestTemplate详解)
    Spring Boot之拦截器与过滤器(完整版)
    Spring中的数据库事物管理
    客户端传入数据的校验-RestController进阶
    拦截器 应用详解--SpringMVC
    MyBatis学习笔记
    oracle数据库之rownum和rowid用法
    Oracle数据库之分组查询及排序
    oracle数据库之子查询
    oracle数据库之组函数
  • 原文地址:https://www.cnblogs.com/kls123/p/9600663.html
Copyright © 2011-2022 走看看