AC日记——【模板】普通平衡树(Treap/SBT) 洛谷 P3369

【模板】普通平衡树(Treap/SBT)

思路:

  劳资敲了一个多星期;

  劳资终于a了;

  劳资一直不a是因为一个小错误;

  劳资最后看的模板;

  劳资现在很愤怒;

  劳资不想谈思路!!!

来,上代码:

#include <cstdio>

using namespace std;

#define maxn 1000005

struct SplayTreeNodeType {
    int w,key,opi,size,ch[2];
};
struct SplayTreeNodeType tree[maxn];

int n,root,tot;

inline void updata(int now)
{
    tree[now].size=tree[now].w;
    if(tree[now].ch[0]) tree[now].size+=tree[tree[now].ch[0]].size;
    if(tree[now].ch[1]) tree[now].size+=tree[tree[now].ch[1]].size;
}

inline int pre()
{
    int now=tree[root].ch[0];
    while(tree[now].ch[1]) now=tree[now].ch[1];
    return now;
}

inline int suc()
{
    int now=tree[root].ch[1];
    while(tree[now].ch[0]) now=tree[now].ch[0];
    return now;
}

inline int getson(int now)
{
    return tree[tree[now].opi].ch[1]==now;
}

void rotate(int now)
{
    int opi=tree[now].opi,fopi=tree[opi].opi,pos=getson(now);
    tree[opi].ch[pos]=tree[now].ch[pos^1];
    tree[tree[opi].ch[pos]].opi=opi;
    tree[now].ch[pos^1]=opi;tree[opi].opi=now;
    tree[now].opi=fopi;
    if(fopi) tree[fopi].ch[tree[fopi].ch[1]==opi]=now;
    updata(opi),updata(now);
}

void splay(int now)
{
    for(int opi;opi=tree[now].opi;rotate(now))
    {
        if(tree[opi].opi) rotate(getson(now)==getson(opi)?opi:now);
    }
    root=now;
}

int rank(int x)
{
    int now=root,ans=0;
    while(1)
    {
        if(x<tree[now].key) now=tree[now].ch[0];
        else
        {
            ans+=tree[now].ch[0]?tree[tree[now].ch[0]].size:0;
            if(x==tree[now].key)
            {
                splay(now);
                return ans+1;
            }
            ans+=tree[now].w;
            now=tree[now].ch[1];
        }
    }
}

int rank_(int x)
{
    int now=root;
    while(1)
    {
        if(tree[now].ch[0]&&x<=tree[tree[now].ch[0]].size) now=tree[now].ch[0];
        else
        {
            int tmp=(tree[now].ch[0]?tree[tree[now].ch[0]].size:0)+tree[now].w;
            if(x<=tmp) return tree[now].key;
            x-=tmp;now=tree[now].ch[1];
        }
    }
}

inline void clear(int now)
{
    tree[now].ch[0]=tree[now].ch[1]=tree[now].w=tree[now].size=tree[now].key=tree[now].opi=0;
}

inline void create(int x)
{
    tree[++tot].key=x;
    tree[tot].w=tree[tot].size=1;
    tree[tot].ch[0]=tree[tot].ch[1]=tree[tot].opi=0;
}

void insert(int x)
{
    if(!root) create(x),root=tot;
    else
    {
        int now=root,opi=0;
        while(1)
        {
            if(tree[now].key==x)
            {
                tree[now].w++;
                tree[now].size++;
                splay(now);
                break;
            }
            opi=now;
            now=tree[now].ch[x>tree[opi].key];
            if(!now)
            {
                create(x);
                tree[tot].opi=opi;
                tree[opi].ch[x>tree[opi].key]=tot;
                splay(tot);
                break;
            }
        }
    }
}

void del(int x)
{
    int t=rank(x);
    if(tree[root].w>1)
    {
        tree[root].w--;
        tree[root].size--;
        return ;
    }
    if(!tree[root].ch[0]&&!tree[root].ch[1])
    {
        clear(root);
        root=0;
        return ;
    }
    if(!tree[root].ch[0])
    {
        int tmp=root;
        root=tree[root].ch[1];
        tree[root].opi=0;
        clear(tmp);
        return ;
    }
    if(!tree[root].ch[1])
    {
        int tmp=root;
        root=tree[root].ch[0];
        tree[root].opi=0;
        clear(tmp);
        return ;
    }
    int pre1=pre(),tmp=root;
    splay(pre1);
    tree[root].ch[1]=tree[tmp].ch[1];
    tree[tree[tmp].ch[1]].opi=root;
    clear(tmp);updata(root);
}

inline void in(int &now)
{
    register int if_z=1;now=0;
    register char Cget=getchar();
    while(Cget>‘9‘||Cget<‘0‘)
    {
        if(Cget==‘-‘) if_z=-1;
        Cget=getchar();
    }
    while(Cget>=‘0‘&&Cget<=‘9‘)
    {
        now=now*10+Cget-‘0‘;
        Cget=getchar();
    }
    now*=if_z;
}

int main()
{
    in(n);int ty,x;
    while(n--)
    {
        in(ty),in(x);
        if(ty==1) insert(x);
        if(ty==2) del(x);
        if(ty==3) printf("%d\n",rank(x));
        if(ty==4) printf("%d\n",rank_(x));
        if(ty==5) insert(x),printf("%d\n",tree[pre()].key),del(x);
        if(ty==6) insert(x),printf("%d\n",tree[suc()].key),del(x);
    }
    return 0;
}
时间: 2024-11-05 20:19:58

AC日记——【模板】普通平衡树(Treap/SBT) 洛谷 P3369的相关文章

luoguP3369[模板]普通平衡树(Treap/SBT) 题解

链接一下题目:luoguP3369[模板]普通平衡树(Treap/SBT) #include<iostream> #include<cstdlib> #include<cstdio> #include<cmath> #include<cstring> #include<iomanip> #include<algorithm> #include<ctime> #include<queue> #incl

AC日记——[USACO15DEC]最大流Max Flow 洛谷 P3128

题目描述 Farmer John has installed a new system of  pipes to transport milk between the  stalls in his barn (), conveniently numbered . Each pipe connects a pair of stalls, and all stalls are connected to each-other via paths of pipes. FJ is pumping milk

AC日记——[HNOI2010]BOUNCE 弹飞绵羊 洛谷 P3203

[HNOI2010]BOUNCE 弹飞绵羊 思路: SBlct: 代码: #include <bits/stdc++.h> using namespace std; #define maxn 200005 int n,m,f[maxn],ch[maxn][2],rev[maxn],ki[maxn],sta[maxn],top,lit,size[maxn]; inline void in(int &now) { char Cget=getchar();now=0; while(Cget&

AC日记——让我们异或吧 洛谷 P2420

题目描述 异或是一种神奇的运算,大部分人把它总结成不进位加法. 在生活中…xor运算也很常见.比如,对于一个问题的回答,是为1,否为0.那么: (A是否是男生 )xor( B是否是男生)=A和B是否能够成为情侣 好了,现在我们来制造和处理一些复杂的情况.比如我们将给出一颗树,它很高兴自己有N个结点.树的每条边上有一个权值.我们要进行M次询问,对于每次询问,我们想知道某两点之间的路径上所有边权的异或值. 输入输出格式 输入格式: 输入文件第一行包含一个整数N,表示这颗开心的树拥有的结点数,以下有N

AC日记——[USACO10MAR]仓配置Barn Allocation 洛谷 P1937

[USACO10MAR]仓配置Barn Allocation 思路: 贪心+线段树维护: 代码: #include <bits/stdc++.h> using namespace std; #define maxn 100005 #define INF 0x3f3f3f3f #define maxtree maxn<<2 struct QueryType { int l,r; bool operator<(const QueryType pos)const { if(pos.

AC日记——斐波那契数列 洛谷 P1962

斐波那契数列 思路: 矩阵快速幂: 来,上代码: #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace std; #define mod 1000000007 struct MatrixType { long long ai[3][3]; void mem() { for(int i=0;i<3;i++) { for(i

AC日记——[USACO11DEC]牧草种植Grass Planting 洛谷 P3038

题目描述 Farmer John has N barren pastures (2 <= N <= 100,000) connected by N-1 bidirectional roads, such that there is exactly one path between any two pastures. Bessie, a cow who loves her grazing time, often complains about how there is no grass on t

【模板】矩阵快速幂 洛谷P2233 [HNOI2002]公交车路线

P2233 [HNOI2002]公交车路线 题目背景 在长沙城新建的环城公路上一共有8个公交站,分别为A.B.C.D.E.F.G.H.公共汽车只能够在相邻的两个公交站之间运行,因此你从某一个公交站到另外一个公交站往往要换几次车,例如从公交站A到公交站D,你就至少需要换3次车. Tiger的方向感极其糟糕,我们知道从公交站A到公交E只需要换4次车就可以到达,可是tiger却总共换了n次车,注意tiger一旦到达公交站E,他不会愚蠢到再去换车.现在希望你计算一下tiger有多少种可能的乘车方案. 题

洛谷 P3369 BZOJ 3224 【模板】普通平衡树(Treap/SBT)

题目描述 您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作: 插入x数 删除x数(若有多个相同的数,因只删除一个) 查询x数的排名(若有多个相同的数,因输出最小的排名) 查询排名为x的数 求x的前驱(前驱定义为小于x,且最大的数) 求x的后继(后继定义为大于x,且最小的数) 输入输出格式 输入格式: 第一行为n,表示操作的个数,下面n行每行有两个数opt和x,opt表示操作的序号(1<=opt<=6) 输出格式: 对于操作3,4,5,6每行输出一个数,表示对应答案 输