• P3369 【模板】普通平衡树(权值线段树)


    原来线段树还有这种操作(开成一个桶)

    用区间维护在这个区间内元素的个数,离散化一下,居然能达到splay的效果

    不仅码量大大减少,而且跑的飞快!!!

    6种操作  200多ms

    1. 插入 xx 数
    2. 删除 xx 数(若有多个相同的数,因只删除一个)
    3. 查询 xx 数的排名(排名定义为比当前数小的数的个数 +1+1 。若有多个相同的数,因输出最小的排名)
    4. 查询排名为 xx 的数
    5. 求 xx 的前驱(前驱定义为小于 xx ,且最大的数)
    6. 求 xx 的后继(后继定义为大于 xx ,且最小的数)
    #include<cstdio>
    #include<iostream>
    #include<cctype>
    #include<algorithm>
    using namespace std;
    #define int long long
    #define ls (o<<1)
    #define rs (ls|1)
    int b[100500];
    int a[100500];
    int val[100500];
    int st[405000];
    int n;
    int tot;
    inline int read()
    {
        int x=0,f=1;
        char ch=getchar();
        while(!isdigit(ch))
        {
            if(ch=='-')
                f=-f;
            ch=getchar();
        }
        while(isdigit(ch))
        {
            x=(x<<1)+(x<<3)+(ch^48);
            ch=getchar();
        }
        return x*f;
    }
    inline void put(int x)
    {
        if(x<0)
        {
            putchar('-');
            x=-x;
        }
        if(x>9)
            put(x/10);
        putchar(x%10+'0');
    }
    inline void add_or_del(int o,int l,int r,int k,int pos)
    {
        st[o]+=pos;
        if(l==r) return;
        int mid=(l+r)>>1;
        if(k<=mid) add_or_del(ls,l,mid,k,pos);
        else add_or_del(rs,mid+1,r,k,pos);
    }
    inline int x_rank_n(int o,int l,int r,int k)
    {
        if(l==r) return 1;
        int mid=(l+r)>>1;
        if(k<=mid) return x_rank_n(ls,l,mid,k);
        else return st[ls]+x_rank_n(rs,mid+1,r,k);
    }
    inline int n_rank_x(int o,int l,int r,int k)
    {
        if(l==r) return l;
        int mid=(l+r)>>1;
        if(st[ls]>=k) return n_rank_x(ls,l,mid,k);
        else return n_rank_x(rs,mid+1,r,k-st[ls]);
    }
    signed main()
    {
        n=read();
        for(int i=1;i<=n;i++)
        {
            val[i]=read();
            a[i]=read();
            if(val[i]!=4)
                b[++tot]=a[i];
        }
        sort(b+1,b+tot+1);
        for(int i=1;i<=n;i++)
        {
            if(val[i]!=4)
                a[i]=lower_bound(b+1,b+tot+1,a[i])-b;
        }
        for(int i=1;i<=n;i++)
        {
            switch(val[i])
            {
                case 1: add_or_del(1,1,tot,a[i],1);break;
                case 2: add_or_del(1,1,tot,a[i],-1);break;
                case 3: put(x_rank_n(1,1,tot,a[i]));putchar('
    ');break;
                case 4: put(b[n_rank_x(1,1,tot,a[i])]);putchar('
    ');break;
                case 5: put(b[n_rank_x(1,1,tot,x_rank_n(1,1,tot,a[i])-1)]);putchar('
    ');break;
                default: put(b[n_rank_x(1,1,tot,x_rank_n(1,1,tot,a[i]+1))]);putchar('
    ');
            }
        }
        return 0;
    }

    so   good。。。

    ----olinr
  • 相关阅读:
    【分享】项目开发容易出现的问题?身为前端/后端你见到过吗?
    标准化API设计的重要性
    【分享】对外API接口安全设计
    【实例】调用数据库自动生成接口代码
    【翻译】API-First是什么概念?有什么商业价值?
    保障接口安全的5种常见方式
    【翻译】使用OpenAPI规范进行安全的API设计
    为什么需要API文档
    利用java的反射,实现工厂创建对象
    Cesium入门8
  • 原文地址:https://www.cnblogs.com/olinr/p/9414963.html
Copyright © 2020-2023  润新知