bzoj1208

splay 120ms

#include<cstdio>
#include<cctype>
#include<algorithm>
#define maxn 80002
#define mod 1000000
using namespace std;
int n,rt,typ,sz,ans,t1,t2;
int cnt[maxn],siz[maxn],f[maxn],tr[maxn][2],key[maxn];

inline void read(int &x){
    char ch=getchar();x=0;int f=1;
    while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
    while(isdigit(ch)){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
    x*=f;
}

inline void clear(int x){
    tr[x][0]=tr[x][1]=f[x]=siz[x]=cnt[x]=key[x]=0;
}

void updata(int x){
    if(x){
        siz[x]=cnt[x];
        if(tr[x][0])siz[x]+=siz[tr[x][0]];
        if(tr[x][1])siz[x]+=siz[tr[x][1]];
    }
}

void rotate(int x){
    int old=f[x],oldf=f[old],whicx=(tr[f[x]][1]==x);
    tr[old][whicx]=tr[x][whicx^1];f[tr[old][whicx]]=old;
    tr[x][whicx^1]=old;f[old]=x;
    f[x]=oldf;
    if(oldf)tr[oldf][tr[oldf][1]==old]=x;
    updata(old);updata(x);
}

void splay(int x){
    for(int fa;fa=f[x];rotate(x))
       if(f[fa])rotate((tr[f[x]][1]==x)==(tr[f[fa]][1]==fa)?fa:x);
    rt=x;
}

void insert(int x){
    if(!rt){sz++;tr[sz][0]=tr[sz][1]=f[sz]=0;rt=sz;siz[sz]=cnt[sz]=1;key[sz]=x;return;}//
    int now=rt,fa=0;
    while(1){
        if(x==key[now]){cnt[now]++;updata(now);updata(fa);splay(now);break;}
        fa=now;
        now=tr[now][key[now]<x];
        if(now==0){
            sz++;
            tr[sz][0]=tr[sz][1]=0;
            f[sz]=fa;
            siz[sz]=cnt[sz]=1;
            tr[fa][key[fa]<x]=sz;
            key[sz]=x;
            updata(fa);
            splay(sz);
            break;
        }
    }
}
(一开始没看题目,考虑了特点值和希望值一样的情况)
inline int pre(){
    int now=tr[rt][0];
    while(tr[now][1])now=tr[now][1];
    return now; 
}
inline int nex(){
    int now=tr[rt][1];
    while(tr[now][0])now=tr[now][0];
    return now;
}

inline void pre(int b){
    for(int x=rt;x;){
        if(key[x]<=b){t1=x;x=tr[x][1];}else x=tr[x][0];
    }
}
inline void nex(int b){
    for(int x=rt;x;){
        if(key[x]>=b){t2=x;x=tr[x][0];}else x=tr[x][1];
    }
} 

void del(int x){
    splay(x);
    if(cnt[rt]>1){cnt[rt]--;updata(rt);return;}
    if(!tr[rt][0]&&!tr[rt][1]){clear(rt);rt=0;return;}
    if(!tr[rt][0]){int oldrt=rt;rt=tr[rt][1];f[rt]=0;clear(oldrt);return;}
    if(!tr[rt][1]){int oldrt=rt;rt=tr[rt][0];f[rt]=0;clear(oldrt);return;}
    int lefb=pre(),oldrt=rt;
    splay(lefb);
    tr[rt][1]=tr[oldrt][1];
    f[tr[oldrt][1]]=rt;
    clear(oldrt);
    updata(rt);
}

int main(){
    read(n);
    int a,b;
    while(n--){
        read(a);read(b);
        if(!rt){typ=a;insert(b);}else
        if(a==typ)insert(b);
        else{
            t1=t2=-1;
            pre(b);nex(b);
            if(t1==-1){ans+=key[t2]-b;ans%=mod;del(t2);}else
            if(t2==-1){ans+=b-key[t1];ans%=mod;del(t1);}else{
                if(b-key[t1]>key[t2]-b){ans+=key[t2]-b;ans%=mod;del(t2);}
                else{ans+=b-key[t1];ans%=mod;del(t1);}
            }
        }
    }
    printf("%d\n",ans);
}

sbt(抄板子的)216ms

#include<cstdio>
#include<cstring>
#include<cctype>
#define mod 1000000
#define maxn 80001
using namespace std;
int rt,sz,man,n;
struct data{int l,r,siz,key;void init(int val){l=r=0;siz=1;key=val;}}sbt[maxn];

inline void read(int &x){
    char ch=getchar();x=0;int f=1;
    while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
    while(isdigit(ch)){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
    x*=f;
}

void zig(int &t){
    int k=sbt[t].r;
    sbt[t].r=sbt[k].l;
    sbt[k].l=t;
    sbt[k].siz=sbt[t].siz;
    sbt[t].siz=sbt[sbt[t].l].siz+sbt[sbt[t].r].siz+1;
    t=k;
}

void zag(int &t){
    int k=sbt[t].l;
    sbt[t].l=sbt[k].r;
    sbt[k].r=t;
    sbt[k].siz=sbt[t].siz;
    sbt[t].siz=sbt[sbt[t].l].siz+sbt[sbt[t].r].siz+1;
    t=k;
}
void maintain(int &x,bool flag){
    if(!flag){
        if(sbt[sbt[sbt[x].l].l].siz>sbt[sbt[x].r].siz)zag(x);
        else if(sbt[sbt[sbt[x].l].r].siz>sbt[sbt[x].r].siz){
            zig(sbt[x].l);zag(x);
        }else return;
    }
    else{
        if(sbt[sbt[sbt[x].r].r].siz>sbt[sbt[x].l].siz)zig(x);
        else if(sbt[sbt[sbt[x].r].l].siz>sbt[sbt[x].l].siz){
            zag(sbt[x].r);zig(x);
        }else return;
    }
    maintain(sbt[x].l,0);
    maintain(sbt[x].r,1);
    maintain(x,0);
    maintain(x,1);
}
void insert(int &x,int key){
    if(!x){x=++sz;sbt[x].init(key);}
    else{
        sbt[x].siz++;
        insert(key<sbt[x].key?sbt[x].l:sbt[x].r,key);
        maintain(x,key>=sbt[x].key);
    }
}

int del(int &x,int key){
    if(!x)return 0;
    sbt[x].siz--;
    if(key==sbt[x].key||(key<sbt[x].key&&!sbt[x].l)||(key>sbt[x].key&&!sbt[x].r)){
        if(sbt[x].l&&sbt[x].r){
            int pos=del(sbt[x].l,key+1);
            sbt[x].key=sbt[pos].key;
            return pos;
        }else{
            int pos=x;
            x=sbt[x].l+sbt[x].r;
            return pos;
        }
    }
        else return del(key<sbt[x].key?sbt[x].l:sbt[x].r,key);
}

int pre(int x,int key){
    if(!x)return key;
    if(key<=sbt[x].key)return pre(sbt[x].l,key);
    else{
        int tmp=pre(sbt[x].r,key);
        return key==tmp?sbt[x].key:tmp;
    }
}

int nex(int x,int key){
    if(!x)return key;
    if(key>=sbt[x].key)return nex(sbt[x].r,key);
    else{
        int tmp=nex(sbt[x].l,key);
        return key==tmp?sbt[x].key:tmp;
    }
}

int main(){
   while(scanf("%d",&n)!=EOF){
    int a,b,typ,ans=0;rt=sz=0;
    while(n--){
        read(a);read(b);
        if(!rt){
            man=a;insert(rt,b);
        }
        else{
            if(man==a)insert(rt,b);
            else {
                int x=pre(rt,b);int y=nex(rt,b);
                int tmp1=b-x,tmp2=y-b;
                if(tmp1==0){ans=(ans+tmp2)%mod;del(rt,y);}
                else if(tmp2==0){ans=(ans+tmp1)%mod;del(rt,x);}
                else if(tmp1<=tmp2){ans=(ans+tmp1)%mod;del(rt,x);}
                else {ans=(ans+tmp2)%mod;del(rt,y);}
            }
        }
    }
    printf("%d\n",ans);
   }
}

 

转载于:https://www.cnblogs.com/MikuKnight/p/9045155.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值