bzoj1208 寵物收養所

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)。【任務描述】你獲得了一年當中,領養者和被收養寵物到來收養所的狀況,但願你計算全部收養了寵物的領養者的不滿意程度的總和。這一年初始時,收養所裏面既沒有寵物,也沒有領養者。node

Input

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

Output

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

Sample Input

5
0 2
0 4
1 3
1 2
1 5

Sample Output

3
(abs(3-2) + abs(2-4)=3,最後一個領養者沒有寵物能夠領養)
 
 
Treap,求一下前驅和後繼就行。
一開始覺得要寫兩顆平衡樹,其實只用寫一顆,由於保證一顆樹上有東西是另外一顆是空着的,只用記錄一下樹的大小。
最後被卡了一個點,由於附的極大值太大了,最後致使爆int了。
 
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <cstring>
#define in(a) a=read()
#define MAXN 80010
#define REP(i,k,n)  for(int i=k;i<=n;i++)
using namespace std;
inline int read(){
    int x=0,f=1;
    char ch=getchar();
    for(;!isdigit(ch);ch=getchar())
        if(ch='-')
            f=-1;
    for(;isdigit(ch);ch=getchar())
        x=x*10+ch-'0';
    return x*f;
}
int n,has,book;
int root,total,ans;
struct node{
    int l,r,size,c,key,data;
}tree[MAXN];
inline int ran(){
    int t=(rand()+19260817)%2147483647;
    return (t*10000007LL)%2147483647;
}
inline void update(int i){
    tree[i].size=tree[tree[i].l].size+tree[tree[i].r].size+tree[i].c;
    return ;
}
inline void zag(int &i){
    int t=tree[i].r;
    tree[i].r=tree[t].l;
    tree[t].l=i;
    tree[t].size=tree[i].size;
    update(i);
    i=t;
    return ;
}
inline void zig(int &i){
    int t=tree[i].l;
    tree[i].l=tree[t].r;
    tree[t].r=i;
    tree[t].size=tree[i].size;
    update(i);
    i=t;
    return ;
}
inline void insert(int &i,int k){
    if(!i){
        i=++total;
        tree[i].key=ran();
        tree[i].c=tree[i].size=1;
        tree[i].data=k;
        return ;
    }
    tree[i].size++;
    if(tree[i].data==k)  tree[i].c++;
    else  if(tree[i].data>k){
        insert(tree[i].l,k);
        if(tree[tree[i].l].key<tree[i].key)  zig(i);
    }
    else{
        insert(tree[i].r,k);
        if(tree[tree[i].r].key<tree[i].key)  zag(i);
    }
    return ;
}
inline void delate(int &i,int k){
    if(!i)  return ;
    if(tree[i].data==k){
        if(tree[i].c>1)  tree[i].c--,tree[i].size--;
        else{
            if(!tree[i].l || !tree[i].r)  i=tree[i].l+tree[i].r;
            else  if(tree[tree[i].l].key<tree[tree[i].r].key)  zig(i),delate(i,k);
            else  zag(i),delate(i,k);
        }
    }
    else if(k<tree[i].data)  tree[i].size--,delate(tree[i].l,k);
    else  tree[i].size--,delate(tree[i].r,k);
    return ;
}
inline int getfront(int i,int k){
    if(!i)  return -214748364;
    if(k>=tree[i].data)  return max(tree[i].data,getfront(tree[i].r,k));
    else  return getfront(tree[i].l,k);
}
inline int getback(int i,int k){
    if(!i)  return 214748364;
    if(k<=tree[i].data)  return min(tree[i].data,getback(tree[i].l,k));
    else  return getback(tree[i].r,k);
}
int main(){
    in(n);
    int a,b;
    REP(i,1,n){
        in(a),in(b);
        if(!has){
            insert(root,b);
            book=a,has=1;
            continue;
        }
        if(a!=book){
            int k1=getfront(root,b);
            int k2=getback(root,b);
            if(abs(k1-b)>abs(k2-b)){
                ans=(ans+abs(k2-b))%1000000;
                delate(root,k2);
                has--;
            }
            else{
                ans=(ans+abs(k1-b))%1000000;
                delate(root,k1);
                has--;
            }
            continue;
        }
        if(a==book)  insert(root,b),has++;
    }
    printf("%d",ans);
    return 0; 
}
相關文章
相關標籤/搜索