bzoj1208: [HNOI2004]宠物收养所 SBT&&Splay

来源:互联网 发布:us域名注册 编辑:程序博客网 时间:2024/04/30 16:03
初次写SBT。。。。。感觉sbt跟线段树一样,多写写就熟了。
#include <iostream>#include <algorithm>#include <cstdio>#include <cstring>#include <queue>using namespace std;#define maxn 1100000#define mod 1000000#define INF 1e9int root,siz[maxn],val[maxn],ls[maxn],rs[maxn];int cnt,people,ans,n;inline int getint(){char c;int res;while (c = getchar(), ('0' > c || c > '9') && c != '-');int flag=1;if(c=='-') flag=-1,res=0;else res=c-'0';    while (c = getchar(), '0' <= c && c <= '9')res = res * 10 + c - '0';    return res*flag;}inline void rotate_l(int &x){    int y=rs[x];    rs[x]=ls[y];    ls[y]=x;    siz[y]=siz[x];    siz[x]=siz[ls[x]]+siz[rs[x]]+1;    x=y;}inline void rotate_r(int &x){    int y=ls[x];    ls[x]=rs[y];    rs[y]=x;    siz[y]=siz[x];    siz[x]=siz[ls[x]]+siz[rs[x]]+1;    x=y;}inline void maintain(int& x,int fg){    if(!fg)    {        if(siz[ls[ls[x]]]>siz[rs[x]]) rotate_r(x);        else if(siz[rs[ls[x]]]>siz[rs[x]]) rotate_l(ls[x]),rotate_r(x);        else return;    }    else    {        if(siz[rs[rs[x]]]>siz[ls[x]]) rotate_l(x);        else if(siz[ls[rs[x]]]>siz[ls[x]]) rotate_r(rs[x]),rotate_l(x);        else return;    }    maintain(ls[x],0); maintain(rs[x],1);    maintain(x,1);    maintain(x,0);}inline void insert(int& x,int b){    if(!x)    {        cnt++;        x=cnt;        ls[x]=rs[x]=0;        siz[x]=1;        val[x]=b;        return ;    }    else    {        siz[x]++;        if(b<val[x]) insert(ls[x],b);        else insert(rs[x],b);        maintain(x,b>=val[x]);    }}inline int pred(int& x,int y,int b){    if(!x) return y;    if(b>val[x]) return pred(rs[x],x,b);    return pred(ls[x],y,b);}inline int succ(int& x,int y,int b){    if(!x) return y;    if(b<val[x]) return succ(ls[x],x,b);    return succ(rs[x],y,b);}int delt(int& x,int b){    siz[x]--;    if(b==val[x]||(b>val[x]&&rs[x]==0)||(b<val[x]&&ls[x]==0))    {        int y=val[x];        if(ls[x]==0||rs[x]==0) x=ls[x]+rs[x];        else val[x]=delt(ls[x],val[x]+1);        return y;    }    else    {        if(b<val[x]) return delt(ls[x],b);        else return delt(rs[x],b);    }}int main(){    int a,b;    int f1,f2;    scanf("%d",&n);    for(int i=1;i<=n;i++)    {        a=getint();        b=getint();        if(siz[root]==0||a==people)        {            people=a;            insert(root,b);            continue;        }        f1=pred(root,0,b);        f2=succ(root,0,b);        if(f1!=0) f1=val[f1];        else f1=INF;        if(f2!=0) f2=val[f2];        else f2=INF;        if(abs(f1-b)<=abs(f2-b)) delt(root,f1),ans+=abs(f1-b)%mod;        else delt(root,f2),ans+=abs(f2-b)%mod;        ans%=mod;    }    printf("%d\n",ans);    return 0;}
这个题用splay竟然比SBT快。。。。96ms
#include <iostream>#include <algorithm>#include <cstdio>#include <cstring>#include <queue>using namespace std;#define maxn 1100000#define mod 1000000#define INF 1e9int root,siz[maxn],val[maxn],tr[maxn][2],fa[maxn];int cnt,people,ans,n,t1,t2;inline int getint(){    char c;    int res;    while (c = getchar(), ('0' > c || c > '9') && c != '-');    int flag=1;    if(c=='-') flag=-1,res=0;    else res=c-'0';    while (c = getchar(), '0' <= c && c <= '9')            res = res * 10 + c - '0';    return res*flag;}inline void rotateup(int x,int& rt){    int l,r,y,z;    y=fa[x];z=fa[y];    if(tr[y][0]==x)l=0;else l=1;r=l^1;    if(y==rt) rt=x;    else    {        if(tr[z][0]==y) tr[z][0]=x;        else tr[z][1]=x;    }    fa[y]=x;fa[x]=z;fa[tr[x][r]]=y;    tr[y][l]=tr[x][r];tr[x][r]=y;}inline void splay(int x,int& rt){    int y,z;    while(x!=rt)    {        y=fa[x];z=fa[y];        if(y!=rt)        {            if( (tr[y][0]==x)^(tr[z][0]==y) ) rotateup(x,rt);            else rotateup(y,rt);        }        rotateup(x,rt);    }}inline void insert(int& x,int last,int b){    if(!x)    {        cnt++;        x=cnt;        val[x]=b;        fa[x]=last;        splay(x,root);        return;    }    if(b<val[x]) insert(tr[x][0],x,b);    else insert(tr[x][1],x,b);}inline void pred(int x,int b){     if(x==0)return;     if(val[x]<=b){t1=x,pred(tr[x][1],b);}     else pred(tr[x][0],b);}inline void succ(int x,int b){     if(x==0)return;     if(val[x]>=b){t2=x,succ(tr[x][0],b);}     else succ(tr[x][1],b);}inline void delt(int x){splay(x,root);if(tr[x][0]*tr[x][1]==0){    root=tr[x][0]+tr[x][1];    }else{int k=tr[x][1];while(tr[k][0])k=tr[k][0];tr[k][0]=tr[x][0];fa[tr[x][0]]=k;root=tr[x][1];}fa[root]=0;}int main(){    int a,b;    int f1,f2;    scanf("%d",&n);    for(int i=1;i<=n;i++)    {        a=getint();        b=getint();        if(!root)        {            people=a;            insert(root,0,b);            continue;        }        else if(a==people)        {            insert(root,0,b);            continue;        }        else{t1=t2=-1;pred(root,b);succ(root,b);if(t1==-1){ans+=val[t2]-b;ans%=1000000;delt(t2);}else if(t2==-1){ans+=b-val[t1];ans%=1000000;delt(t1);}else{if(b-val[t1]>val[t2]-b)  {ans+=val[t2]-b;ans%=1000000;delt(t2);}else{ans+=b-val[t1];ans%=1000000;delt(t1);}}}    }    printf("%d\n",ans);    return 0;}

0 0