• bzoj 3196 && luogu 3380 JoyOI 1730 二逼平衡树 (线段树套Treap)


    链接:https://www.lydsy.com/JudgeOnline/problem.php?id=3196

    题面;

    3196: Tyvj 1730 二逼平衡树

    Time Limit: 10 Sec  Memory Limit: 128 MB
    Submit: 6372  Solved: 2406
    [Submit][Status][Discuss]

    Description

    您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作:
    1.查询k在区间内的排名
    2.查询区间内排名为k的值
    3.修改某一位值上的数值
    4.查询k在区间内的前驱(前驱定义为小于x,且最大的数)
    5.查询k在区间内的后继(后继定义为大于x,且最小的数)

    Input

    第一行两个数 n,m 表示长度为n的有序序列和m个操作
    第二行有n个数,表示有序序列
    下面有m行,opt表示操作标号
    若opt=1 则为操作1,之后有三个数l,r,k 表示查询k在区间[l,r]的排名
    若opt=2 则为操作2,之后有三个数l,r,k 表示查询区间[l,r]内排名为k的数
    若opt=3 则为操作3,之后有两个数pos,k 表示将pos位置的数修改为k
    若opt=4 则为操作4,之后有三个数l,r,k 表示查询区间[l,r]内k的前驱
    若opt=5 则为操作5,之后有三个数l,r,k 表示查询区间[l,r]内k的后继

    Output

    对于操作1,2,4,5各输出一行,表示查询结果

    Sample Input

    9 6
    4 2 2 1 9 4 0 1 1
    2 1 4 3
    3 4 10
    2 1 4 3
    1 2 5 9
    4 3 9 5
    5 2 8 5

    Sample Output

    2
    4
    3
    4
    9

    HINT

    1.n和m的数据范围:n,m<=50000


    2.序列中每个数的数据范围:[0,1e8]


    3.虽然原题没有,但事实上5操作的k可能为负数
     
     
    思路;
    线段树套个Treap就完事了,ls写成了rs,找了一晚上的错,真实自闭
     
    实现代码:
    #include<bits/stdc++.h>
    using namespace std;
    #define ls t[x].ch[0]
    #define rs t[x].ch[1]
    #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;
    const int inf = 2147483647;
    int idx,n;
    struct node{
        int ch[2],cnt,siz,val,rd;
    }t[M*50];
    int root[M<<2],a[M];
    void up(int x){
        t[x].siz = t[ls].siz + t[rs].siz+t[x].cnt;
    }
    
    void rotate(int &x,int d){
        int son = t[x].ch[d];
        t[x].ch[d] = t[son].ch[d^1];
        t[son].ch[d^1] = x; up(x); up(x=son);
    }
    
    void ins(int &x,int val){
        if(!x){
            x = ++idx;
            t[x].cnt = t[x].siz = 1;
            t[x].val = val,t[x].rd = rand();
            return ;
        }
        t[x].siz ++;
        if(t[x].val == val){
            t[x].cnt++; return ;
        }
        int d = t[x].val < val; ins(t[x].ch[d],val);
        if(t[x].rd > t[t[x].ch[d]].rd) rotate(x,d);
    }
    
    void del(int &x,int val){
        if(!x) return ;
        if(t[x].val == val){
            if(t[x].cnt > 1){
                t[x].cnt--,t[x].siz--;return ;
            }
            bool d = t[ls].rd > t[rs].rd;
            if(ls == 0||rs == 0) x = ls+rs;
            else rotate(x,d),del(x,val);
        }
        else t[x].siz--,del(t[x].ch[t[x].val<val],val);
        up(x);
    }
    int rk(int x,int val){
        if(!x) return 0;
        if(t[x].val == val) return t[ls].siz;
        if(t[x].val > val) return rk(ls,val);
        return rk(rs,val)+t[ls].siz + t[x].cnt;
    }
    
    int pre(int x,int val){
        if(!x) return -inf;
        if(t[x].val >= val) return pre(ls,val);
        return max(pre(rs,val),t[x].val);
    }
    
    int nex(int x,int val){
        if(!x) return inf;
        if(t[x].val <= val) return nex(rs,val);
        return min(nex(ls,val),t[x].val);
    }
    
    void print(int x){
        if(!x) return ;
        print(ls);
        printf("%d ",t[x].val);
        print(rs);
    }
    
    void update(int p,int l,int r,int rt){
        ins(root[rt],a[p]);
        if(l == r) return ;
        mid;
        if(p <= m) update(p,lson);
        else update(p,rson);
    }
    
    int get_rank(int L,int R,int c,int l,int r,int rt){
        if(L <= l&&R >= r){
            return rk(root[rt],c);
        }
        int ret = 0;
        mid;
        if(L <= m) ret += get_rank(L,R,c,lson);
        if(R > m) ret += get_rank(L,R,c,rson);
        return ret;
    }
    
    int get_val(int x,int y,int k){
        int l = 0,r = inf,ret ;
        while(l < r){
            mid;
            int ans = get_rank(x,y,m,1,n,1)+1;
            if(ans <= k) {
                ret = m;l = m+1;
            }
            else r = m;
        }
        return ret;
    }
    
    void change(int p,int c,int l,int r,int rt){
        del(root[rt],a[p]);
        ins(root[rt],c);
        if(l == r) return ;
        mid;
        if(p <= m) change(p,c,lson);
        else change(p,c,rson);
    }
    
    int get_pre(int L,int R,int c,int l,int r,int rt){
        if(L <= l&&R >= r){
            return pre(root[rt],c);
        }
        mid;
        int ret = -inf;
        if(L <= m) ret = max(ret,get_pre(L,R,c,lson));
        if(R > m) ret = max(ret,get_pre(L,R,c,rson));
        return ret;
    }
    
    int get_nex(int L,int R,int c,int l,int r,int rt){
        if(L <= l&&R >= r){
            return nex(root[rt],c);
        }
        mid;
        int ret = inf;
        if(L <= m) ret = min(ret,get_nex(L,R,c,lson));
        if(R > m) ret = min(ret,get_nex(L,R,c,rson));
        return ret;
    }
    
    void  ct(int l,int r,int rt){
        cout<<"L R: "<<l<<" "<<r<<endl;
        print(root[rt]); cout<<endl;
        if( l == r) return ;
        mid;
        ct(lson); ct(rson);
    }
    
    int main()
    {
       // freopen("D:\1.txt","r",stdin);
        //freopen("D:\2.txt","w",stdout);
        int m,op,x,y,z;
        scanf("%d%d",&n,&m);
        for(int i = 1;i <= n;i ++){
            scanf("%d",&a[i]);
            update(i,1,n,1);
        }
         //ct(1,n,1);
        while(m--){
            scanf("%d",&op);
            scanf("%d%d",&x,&y);
            if(op!=3) scanf("%d",&z);
            if(op == 1)
                printf("%d
    ",get_rank(x,y,z,1,n,1)+1);
            else if(op == 2)
                printf("%d
    ",get_val(x,y,z));
            else if(op == 3)
                change(x,y,1,n,1),a[x]=y;
            else if(op == 4)
                printf("%d
    ",get_pre(x,y,z,1,n,1));
            else if(op==5)
                printf("%d
    ",get_nex(x,y,z,1,n,1));
        }
        return 0;
    }
  • 相关阅读:
    算法导论第十八章 B树
    腾讯2016春招之算法编程解析
    LeetCode:5_Longest Palindromic Substring | 最长的回文子串 | Medium
    搜狗2016校园招聘之算法编程解析
    linux sed在某些字符串的下一行插入内容?sed在下一行插入?
    linux shell搜索某个字符串,然后在后面加上字符串?字符串后面插入字符串?sed字符串后面插入字符串?
    linux环境中,如何使用tar来创建压缩包?解压缩?
    linux环境中,ssh登录报错,Permission denied, please try again.
    linux环境中安装NRPE插件执行远程"本地资源"检查?NRPE安装?
    linux环境安装nagiosgraph将nagios的性能数据绘制成动态图表?
  • 原文地址:https://www.cnblogs.com/kls123/p/10771704.html
Copyright © 2020-2023  润新知