時間限制: 1 s
空間限制: 128000 kb
題目等級 : 鑽石 diamond
題解題目描述 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 description
第一行為乙個正整數n,n<=80000,表示一年當中來到收養所的寵物和領養者的總數。接下來的n行,按到來時間的先後順序描述了一年當中來到收養所的寵物和領養者的情況。每行有兩個正整數a, b,其中a=0表示寵物,a=1表示領養者,b表示寵物的特點值或是領養者希望領養寵物的特點值。(同一時間呆在收養所中的,要麼全是寵物,要麼全是領養者,這些寵物和領養者的個數不會超過10000個)
輸出描述 output description
僅有乙個正整數,表示一年當中所有收養了寵物的領養者的不滿意程度的總和mod 1000000以後的結果。
樣例輸入 sample input
0 20 4
1 31 2
1 5樣例輸出 sample output
資料範圍及提示 data size & hint
(abs(3-2) + abs(2-4)=3,最後乙個領養者沒有寵物可以領養)
主要是學了splay樹 用來驗板子的
#includeusing namespace std;
const int maxn = 100010;
struct value ///節點內資料
;struct node///ch是左右子樹,f是父親節點,cnt是這個資料出現的次數,size是表示這個樹的大小
t[maxn * 2];
int sz,root;
void init() ///初始化
void clear(int x) ///清空乙個節點
int get(int x) ///獲得這個節點是其父親節點的哪個子樹
void update(int x) ///更新節點大小
}void rotate(int x) ///x節點旋轉操作
t[x].f = k; ///x的父節點變成爺爺節點
t[y].f = x; /// y的父節點變成x
t[y].ch[son] = t[x].ch[son ^ 1]; ///y的 son節點 變成 x 的 son^1 節點
t[t[y]. ch[son]].f = y; /// son^1 節點的父節點變成y節點
t[x].ch[son ^ 1] = y;///x的son^1節點變成y節點
update(y);
update(x);
return ;
}void splay(int x) ///將x節點旋轉至根節點
}root = x;
}void insert(value x) ///將值x 插入樹中
int now = root,fa = 0;
while(1)
fa = now;
now = t[now].ch[ t[now].v.key < x.key]; ///如果插入值小於當前值 就往左子樹插 不然就往右子樹插
if(now == 0) ///新開闢乙個節點
}}int find(value x)///查詢值為 x在樹中的排名
else
if(t[now].v.key == x.key) ///如果是是當前節點就spaly當前節點
ans += t[now].cnt;
now = t[now].ch[1]; ///不然就往右子樹繼續查詢}}
return 0;
}int findx(int x) ///查詢排名為x的值
else
now = t[now].ch[1];
x -= temp;}}
}int pre() ///查詢根節點的前驅節點 (小於x的最大值)
int next() ///查詢根節點的後驅節點 (大於x的最小值)
void del(value x) ///刪除乙個值為x的節點
//如果右多個相同的節點 卻只需要刪除乙個
if(!t[root].ch[0] && !t[root].ch[1])
if(!t[root].ch[0]) ///如果只有單個子節點 就讓那個子節點當根節點
else if(!t[root].ch[1])
int left = pre(),old = root; ///如果有兩個子節點,那就把前驅節點splay到跟節點 然後讓原根節點的右子樹 接到當前跟節點
splay(left);
t[root].ch[1] = t[old].ch[1];
t[t[old].ch[1] ].f = root;
clear(old);
update(root);
}void watch(int x) ///前序遍歷當前子樹
int main()
insert(temp);
int pr = t[pre()].v.key;
int ne = t[next()].v.key;
del(temp);
if(pr == 0)
pr = ne + 1;
if(ne == 0)
ne = pr;
///printf("pr = %d ne = %d\n",pr,ne);
if( abs(pr - temp.key) <= abs(ne - temp.key))
else
///printf("root = %d\n",root);
}else
///watch(root);
}cout
}
wikioi 1285 寵物收養所
演算法 splay 剛開始看到這題,就注意到特徵abs了,並且資料n 80000顯然不能暴力,只能用nlgn的做法,綜合起來,似乎只有乙個答案 splay。將每次插入的點splay到樹根,然後找到它的前驅和後繼,再取它的絕對值即可,我們記作 abs。那麼答案就為sum,其中i為領養的人的數量,可以看...
HNOI2004寵物收養所
time limit 10 sec memory limit 162 mb submit 2796 solved 995 submit status discuss 最近,阿q開了一間寵物收養所。收養所提供兩種服務 收養被主人遺棄的寵物和讓新的主人領養這些寵物。每個領養者都希望領養到自己滿意的寵物,...
Treap BZOJ 1208 寵物收養所
題目描述 最近,阿q開了一間寵物收養所。收養所提供兩種服務 收養被主人遺棄的寵物和讓新的主人領養這些寵物。每個領養者都希望領養到自己滿意的寵物,阿q根據領養者的要求通過他自己發明的乙個特殊的公式,得出該領養者希望領養的寵物的特點值a a是乙個正整數,a 2 31 而他也給每個處在收養所的寵物乙個特點...