1. 程式人生 > >BZOJ 1208: [HNOI2004]寵物收養所

BZOJ 1208: [HNOI2004]寵物收養所

char 分享 整數 到來 content hide des problem pan

Time Limit: 10 Sec Memory Limit: 162 MB
Submit: 9314 Solved: 3732
[Submit][Status][Discuss]

Description

最近,阿Q開了一間寵物收養所。收養所提供兩種服務:收養被主人遺棄的寵物和讓新的主人領養這些寵物。每個領養者都希望領養到自己滿意的寵物,阿Q根據領養者的要求通過他自己發明的一個特殊的公式,得出該領養者希望領養的寵物的特點值a(a是一個正整數,a<2^31),而他也給每個處在收養所的寵物一個特點值。這樣他就能夠很方便的處理整個領養寵物的過程了,寵物收養所總是會有兩種情況發生:被遺棄的寵物過多或者是想要收養寵物的人太多,而寵物太少。 1. 被遺棄的寵物過多時,假若到來一個領養者,這個領養者希望領養的寵物的特點值為a,那麽它將會領養一只目前未被領養的寵物中特點值最接近a的一只寵物。(任何兩只寵物的特點值都不可能是相同的,任何兩個領養者的希望領養寵物的特點值也不可能是一樣的)如果有兩只滿足要求的寵物,即存在兩只寵物他們的特點值分別為a-b和a+b,那麽領養者將會領養特點值為a-b的那只寵物。 2. 收養寵物的人過多,假若到來一只被收養的寵物,那麽哪個領養者能夠領養它呢?能夠領養它的領養者,是那個希望被領養寵物的特點值最接近該寵物特點值的領養者,如果該寵物的特點值為a,存在兩個領養者他們希望領養寵物的特點值分別為a-b和a+b,那麽特點值為a-b的那個領養者將成功領養該寵物。 一個領養者領養了一個特點值為a的寵物,而它本身希望領養的寵物的特點值為b,那麽這個領養者的不滿意程度為abs(a-b)。【任務描述】你得到了一年當中,領養者和被收養寵物到來收養所的情況,希望你計算所有收養了寵物的領養者的不滿意程度的總和。這一年初始時,收養所裏面既沒有寵物,也沒有領養者。

Input

第一行為一個正整數n,n<=80000,表示一年當中來到收養所的寵物和領養者的總數。接下來的n行,按到來時間的先後順序描述了一年當中來到收養所的寵物和領養者的情況。每行有兩個正整數a, b,其中a=0表示寵物,a=1表示領養者,b表示寵物的特點值或是領養者希望領養寵物的特點值。(同一時間呆在收養所中的,要麽全是寵物,要麽全是領養者,這些寵物和領養者的個數不會超過10000個)

Output

僅有一個正整數,表示一年當中所有收養了寵物的領養者的不滿意程度的總和mod 1000000以後的結果。

Sample Input

5
0 2
0 4
1 3
1 2
1 5

Sample Output

3
(abs(3-2) + abs(2-4)=3,最後一個領養者沒有寵物可以領養)

HINT

Source

splay

因為沒領到寵物的人有待定權,所以只會存在兩種情況:1.全是人 2.全是寵物

但本弱雞卡了一上午

死也不知道為什麽一直寫的splay很慢。。

可能是由於所有操作用遞歸完成容易炸(有興趣的可幫忙看看)

於是在ZlycerQan(某位巨佬)的指引下換了種splay寫法。。(不到特殊情況不寫這種。。)

屠龍寶刀點擊就送

技術分享
#include <ctype.h>
#include <cstdio>
#define
N 100000 #define INF 0x7fffffff inline void read(int &x) { x=0;bool f=0; register char ch=getchar(); for(;!isdigit(ch);ch=getchar()) if(ch==-) f=1; for(; isdigit(ch);ch=getchar()) x=(x<<3)+(x<<1)+ch-0; x=f?(~x)+1:x; } int v1,v2,zr,ans,root,n,cn,data[N],cnt[N],siz[N],fa[N],ch[N][2]; inline void pushup(int rt) {siz[rt]=siz[ch[rt][0]]+siz[ch[rt][1]]+cnt[rt];} inline int son(int x) {return ch[fa[x]][1]==x;} inline void rotate(int x) { int y=fa[x],z=fa[y],b=son(x),c=son(y),a=ch[x][!b]; if(z) ch[z][c]=x;else root=x;fa[x]=z; if(a) fa[a]=y;ch[y][b]=a; ch[x][!b]=y;fa[y]=x; pushup(y);pushup(x); } void splay(int x,int i) { while(fa[x]!=i) { int y=fa[x],z=fa[y]; if(z==i) rotate(x); else { if(son(x)==son(y)) { rotate(y); rotate(x); } else { rotate(x); rotate(x); } } } } void ins(int &rt,int x) { if(rt==0) { rt=++cn; data[cn]=x; cnt[cn]=siz[cn]=1; splay(cn,0); return; } if(data[rt]==x) { cnt[rt]++; siz[rt]++; splay(rt,0); return; } if(x<data[rt]) { ins(ch[rt][0],x); fa[ch[rt][0]]=rt; pushup(rt); } else { ins(ch[rt][1],x); fa[ch[rt][1]]=rt; pushup(rt); } } void getpre(int rt,int x) { int p=rt;v1=-1; while(p) { if(x<=data[p]) p=ch[p][0]; else { v1=p; p=ch[p][1]; } } } void getsuc(int rt,int x) { int p=rt;v2=-1; while(p) { if(x>=data[p]) p=ch[p][1]; else { v2=p; p=ch[p][0]; } } } int getmn(int rt) { int p=rt,ans=-1; while(p) { ans=p; p=ch[p][0]; } return ans; } void del(int rt,int x) { if(data[rt]==x) { if(cnt[rt]>1) { cnt[rt]--; siz[rt]--; } else { splay(rt,0); int p=getmn(ch[rt][1]); if(p!=-1) { splay(p,rt); root=p;fa[p]=0; ch[p][0]=ch[rt][0]; fa[ch[rt][0]]=p; } else { root=ch[rt][0]; fa[ch[rt][0]]=0; } } return ; } if(x<data[rt]) { del(ch[rt][0],x); pushup(rt); } else { del(ch[rt][1],x); pushup(rt); } } int main(int argc,char *argv[]) { read(n); for(int x,y;n--;) { read(x); read(y); if((x&&zr<0)||(!x&&zr>0)) { int o,p,pos; ins(root,y); getpre(root,y); getsuc(root,y); del(root,y); int x1=(v1!=-1)?y-data[v1]:INF,x2=(v2!=-1)?data[v2]-y:INF; if(x1>x2) o=x2,p=data[v2],pos=v2; else o=x1,p=data[v1],pos=v1; ans=(ans+o)%1000000; del(root,p); } else ins(root,y); zr+=x?1:-1; } printf("%d\n",ans%1000000); return 0; }
T掉的splay
#include <ctype.h>
#include <cstdio>
#define N 100000
#define INF 0x7fffffff

inline void read(int &x)
{
    x=0;bool f=0;register char ch=getchar();
    for(;!isdigit(ch);ch=getchar()) if(ch==-) f=1;
    for(; isdigit(ch);ch=getchar()) x=(x<<3)+(x<<1)+ch-0;
    x=f?(~x)+1:x; 
}
int ans,n,cn,zr,root,cnt[N],siz[N],data[N],ch[N][2],fa[N];
inline int son(int x) {return ch[fa[x]][1]==x;}
inline void pushup(int x)
{
    siz[x]=cnt[x];
    if(ch[x][0]) siz[x]+=siz[ch[x][0]];
    if(ch[x][1]) siz[x]+=siz[ch[x][1]];
}
void rotate(int x)
{
    int y=fa[x],z=fa[y],b=son(x),c=son(y),a=ch[x][!b];
    if(z) ch[z][c]=x;else root=x;fa[x]=z;
    if(a) fa[a]=y;ch[y][b]=a;
    ch[x][!b]=y;fa[y]=x;
    pushup(y);pushup(x);
}
int splay(int x)
{
    for(int y;y=fa[x];rotate(x))
        if(fa[y])
            rotate(son(x)==son(y)?y:x);
    root=x;
}
int getpre()
{
    int now=ch[root][0];
    while(ch[now][1]) now=ch[now][1];
    return now;
}
int getsuc()
{
    int now=ch[root][1];
    while(ch[now][0]) now=ch[now][0];
    return now;
}
void ins(int x)
{
    if(!root)
    {
        root=++cn;
        data[cn]=x;
        siz[cn]=cnt[cn]=1;
        return;
    }
    int y=0,now=root;
    while(1)
    {
        if(data[now]==x)
        {
            siz[now]++;
            cnt[now]++;
            splay(now);
            return;
        }
        y=now;
        now=ch[now][x>data[y]];
        if(!now)
        {
            cn++;
            ch[y][x>data[y]]=cn;
            fa[cn]=y;
            data[cn]=x;
            siz[cn]=cnt[cn]=1;
            splay(cn);
            return;
        }
    }
}
void clear(int x)
{
    ch[x][0]=ch[x][1]=siz[x]=cnt[x]=data[x]=fa[x]=0;
}
void del()
{
    if(cnt[root]>1)
    {
        siz[root]--;
        cnt[root]--;
        return;
    }
    if(!ch[root][0]&&!ch[root][1])
    {
        clear(root);
        root=0;
        return;
    }
    if(!ch[root][0])
    {
        int tmp=root;
        root=ch[root][1];
        fa[root]=0;
        clear(tmp);
        return;
    }
    if(!ch[root][1])
    {
        int tmp=root;
        root=ch[root][0];
        fa[root]=0;
        clear(tmp);
        return; 
    }
    int tmp=getpre(),pos=root;
    splay(tmp);
    ch[root][1]=ch[pos][1];
    fa[ch[pos][1]]=root;
    clear(pos);
    pushup(root);
}
int main()
{
    read(n);
    for(int x,y;n--;)
    {
        read(x);
        read(y);
        if((x&&zr<0)||(!x&&zr>0))
        {
            int o,p,pos;
            ins(y);
            int v1=getpre(),v2=getsuc();
            int x1=(v1)?y-data[v1]:INF,x2=(v2)?data[v2]-y:INF;
            if(x1>x2) o=x2,p=data[v2],pos=v2;
            else o=x1,p=data[v1],pos=v1;
            ans=(ans+o)%1000000;
            del();splay(pos);del();
        }
        else ins(y);
        zr+=x?1:-1;
    }
    printf("%d",ans%1000000);
    return 0;
}

BZOJ 1208: [HNOI2004]寵物收養所