bzoj1503

treap改了好长时间,erase写错了。。。

#include<iostream>
#include<cstdio>
#include<cstdlib>
using namespace std;
const int inf=1<<29;
int n,mn,root,delta,tot,leave;
int key[100010],cnt[100010],size[100010],p[100010];
int child[100010][2];
void update(int x)
{
    size[x]=size[child[x][0]]+size[child[x][1]]+cnt[x];
}
void rotate(int&x,int t)
{
    int y=child[x][t];
    child[x][t]=child[y][1-t];
    child[y][1-t]=x;
    update(x);
    update(y);
    x=y;
}
void insert(int&x,int k)
{
    if(x)
    {
        if(key[x]==k)
        {
            cnt[x]++;
            update(x);
            return;
        }
        int t=key[x]<k;
        insert(child[x][t],k);
        if(p[x]<p[child[x][t]]) rotate(x,t); 
        update(x);
    }
    else
    {
        tot++;
        x=tot;
        p[x]=rand();
        key[x]=k;
        cnt[x]=1;
        update(x);
    }
}
void erase(int&x,int k)
{
    if(key[x]==k)
    {
        if(!child[x][0]&&!child[x][1])
        {
            x=0;
            return;
        }
        int t=p[child[x][1]]>p[child[x][0]];
        rotate(x,t);
        erase(child[x][t^1],k);
    } else erase(child[x][key[x]<k],k);
    update(x);
}
void _erase(int x)
{
    if(x==0) return;    
    if(key[x]+delta<mn)
    {
        leave+=cnt[x];
        if(key[child[x][0]]+delta<mn) 
        {
            leave+=size[child[x][0]];
            child[x][0]=0;
            update(x);
        }
        _erase(child[x][1]);
        erase(root,key[x]);
    } 
    _erase(child[x][0]);
}
int find(int x,int k)
{
    if(k<=size[child[x][1]]) 
        return find(child[x][1],k);
    k-=size[child[x][1]]+cnt[x];
    if(k<=0) 
        return key[x];
    return find(child[x][0],k);
}
int main()
{
    p[0]=-inf;
    scanf("%d%d",&n,&mn);
    while(n--)
    {
        char s[10]; int k; scanf("%s%d",s,&k);
        if(s[0]=='I')
        {
            if(k>=mn)
                insert(root,k-delta);
        }
        if(s[0]=='A')
        {
            delta+=k;
        }
        if(s[0]=='S')
        {
            delta-=k;
            _erase(root);
        }
        if(s[0]=='F')
        {   
            if(k>size[root]) printf("-1\n"); else
                printf("%d\n",find(root,k)+delta);
        }
    }
    printf("%d\n",leave);
    return 0;
}

 splay

#include<cstdio>
#include<cstring>
using namespace std;
struct data
{
    int fa,l,r,size,cnt,key;
}tree[100010];
int root,n,tot,ans;
int abs(int x)
{
    return x>0?x:-x;
}
void update(int x)
{
    tree[x].size=tree[tree[x].l].size+tree[tree[x].r].size+tree[x].cnt;
}
void zig(int x)
{
    int y=tree[x].fa;
    int z=tree[x].r;
    tree[y].l=z;
    tree[z].fa=y;
    tree[x].fa=tree[y].fa;
    if(y==tree[tree[y].fa].l) tree[tree[y].fa].l=x;
    else tree[tree[y].fa].r=x;
    tree[x].r=y;
    tree[y].fa=x;
    update(x);
    update(y);
}
void zag(int x)
{
    int y=tree[x].fa;
    int z=tree[x].l;
    tree[y].r=z;
    tree[z].fa=y;
    tree[x].fa=tree[y].fa;
    if(y==tree[tree[y].fa].l) tree[tree[y].fa].l=x;
    else tree[tree[y].fa].r=x;
    tree[x].l=y;
    tree[y].fa=x;
    update(x);
    update(y);
}
void splay(int x)
{
    if(!root)
    {
        root=x;
        return;        
    }
    while(tree[x].fa)
    {
        int y=tree[x].fa;
        int z=tree[y].fa;
        if(y==root) 
        {            
            if(x==tree[root].l) zig(x); else zag(x);
            update(x);
            break;
        }
        else if(y==tree[z].l&&x==tree[y].l) {zig(y); zig(x);}
        else if(y==tree[z].r&&x==tree[y].r) {zag(y); zag(x);}
        else if(y==tree[z].l&&x==tree[y].r) {zag(x); zig(x);}
        else if(y==tree[z].r&&x==tree[y].l) {zig(x); zag(x);}
        update(x);
    }
    root=x;
}
void insert(int x,int k)
{    
    if(tree[x].key==k) 
    {
        tree[x].cnt++;
        update(x);
        splay(x);
    } 
    else if(tree[x].key<k) 
    {
        if(tree[x].r==0)
        {
            ++tot;
            tree[tot].fa=x;
            if(x) tree[x].r=tot;
            tree[tot].key=k;
            tree[tot].cnt=1;
            update(tot);
            splay(tot);
            return;
        }
        insert(tree[x].r,k);
        update(x);
    }
    else if(tree[x].key>k) 
    {
        if(tree[x].l==0)
        {
            ++tot;
            tree[tot].fa=x;
            if(x) tree[x].l=tot;
            tree[tot].key=k;
            tree[tot].cnt=1;
            update(tot);
            splay(tot);
            return;
        }
        insert(tree[x].l,k);
        update(x);
    }
}
int search(int x,int k)
{
    if(tree[x].key==k) return x;
    if(tree[x].key<k) return search(tree[x].r,k);
    if(tree[x].key>k) return search(tree[x].l,k);
}
void findnxt(int x,int k,int pd)
{
    if(x==0) return;
    if(pd==5)
    {
        if(tree[x].key<k)
        {
            ans=x;
            findnxt(tree[x].r,k,pd);
        } else findnxt(tree[x].l,k,pd);
    }
    else 
    {
        if(tree[x].key>k)
        {
            ans=x;
            findnxt(tree[x].l,k,pd);
        } else findnxt(tree[x].r,k,pd);
    }
}

void erase(int x)
{
    findnxt(root,x,5);
    int pos=search(root,x);
    splay(pos);
    if(tree[pos].cnt>1) 
    {
        tree[pos].cnt--;
        update(pos);
        splay(pos);
        return;
    }
    if(ans==0)
    {
        root=tree[pos].r;
        tree[root].fa=0;
        return;
    }
    if(tree[x].r==0)
    {
        root=tree[x].l;
        tree[root].fa=0;
        return;
    }
//    printf("%d %d\n",pos,pro);
    tree[tree[pos].r].fa=ans;
    tree[tree[pos].l].fa=0;
    root=tree[pos].l;
    tree[ans].r=tree[pos].r;
    splay(ans);
    ans=0;
}
int findrank(int x)
{
    int pos=search(root,x);
    splay(pos);
    return tree[tree[pos].l].size+1;
}
int find(int x,int k)
{
    int y=tree[x].l;
    int z=tree[x].r;
    if(k<=tree[z].size) return find(z,k);
//    printf("%d %d\n",tree[x].cnt,tree[z].size);
    k-=tree[z].size+tree[x].cnt;
    if(k<=0) return tree[x].key;
    return find(y,k);
}
int main()
{
    scanf("%d",&n);
    while(n--)
    {
        int opt,x; scanf("%d%d",&opt,&x);
         if(opt==1)
         {
             insert(root,x);
         }
         if(opt==2)
         {
             erase(x);
         }
         if(opt==3)
         {
             printf("%d\n",findrank(x));
         }
         if(opt==4)
         {
             printf("%d\n",find(root,x));
         }
         if(opt==5)
         {
             findnxt(root,x,opt);
             printf("%d\n",tree[ans].key);
             ans=0;
         }
         if(opt==6)
         {
             findnxt(root,x,opt);
             printf("%d\n",tree[ans].key);
             ans=0;
         }
    }
    return 0;
}

 

posted @ 2016-11-26 13:12  19992147  阅读(237)  评论(0编辑  收藏  举报