zoukankan      html  css  js  c++  java
  • 「HNOI2004」宠物收养场

    「HNOI2004」宠物收养场

    传送门
    对宠物和人各维护一棵平衡树,每次 ( ext{split}) 的时候记得判一下子树是否为空,然后模拟就好了。
    参考代码:

    #include <algorithm>
    #include <cstdlib>
    #include <cstdio>
    #define rg register
    #define file(x) freopen(x".in", "r", stdin), freopen(x".out", "w", stdout)
    using namespace std;
    template < class T > inline void read(T & s) {
    	s = 0; int f = 0; char c = getchar();
    	while ('0' > c || c > '9') f |= c == '-', c = getchar();
    	while ('0' <= c && c <= '9') s = s * 10 + c - 48, c = getchar();
    	s = f ? -s : s;
    }
    
    const int _ = 8e4 + 5, mod = 1e6;
    
    int n, rt1, rt2, tot, siz[_], val[_], pri[_], ch[2][_];
    
    inline int Newnode(int v)
    { return siz[++tot] = 1, val[tot] = v, pri[tot] = rand(), tot; }
    
    inline void pushup(int p) { siz[p] = siz[ch[0][p]] + siz[ch[1][p]] + 1; }
    
    inline int merge(int x, int y) {
    	if (!x || !y) return x + y;
    	if (pri[x] > pri[y])
    		return ch[1][x] = merge(ch[1][x], y), pushup(x), x;
    	else
    		return ch[0][y] = merge(x, ch[0][y]), pushup(y), y;
    }
    
    inline void split(int p, int v, int& x, int& y) {
    	if (!p) { x = y = 0; return ; }
    	if (val[p] <= v)
    		return x = p, split(ch[1][p], v, ch[1][x], y), pushup(p);
    	else
    		return y = p, split(ch[0][p], v, x, ch[0][y]), pushup(p);
    }
    
    inline int kth(int p, int k) {
    	if (siz[ch[0][p]] + 1 > k) return kth(ch[0][p], k);
    	if (siz[ch[0][p]] + 1 == k) return val[p];
    	if (siz[ch[0][p]] + 1 < k) return kth(ch[1][p], k - siz[ch[0][p]] - 1);
    }
    
    inline void insert(int& rt, int item) {
    	int a, b;
    	split(rt, item, a, b);
    	rt = merge(a, merge(Newnode(item), b));
    }
    
    inline void erase(int& rt, int item) {
    	int a, b, c;
    	split(rt, item, a, c);
    	split(a, item - 1, a, b);
    	b = merge(ch[0][b], ch[1][b]);
    	rt = merge(a, merge(b, c));
    }
    
    inline int match(int& rt, int item) {
    	int a, b, x, y, res;
    	split(rt, item, a, b);
    	if (a == 0 && b != 0) res = kth(b, 1);
    	if (a != 0 && b == 0) res = kth(a, siz[a]);
    	if (a != 0 && b != 0)
    		x = kth(a, siz[a]), y = kth(b, 1), res = item - x <= y - item ? x : y;
    	rt = merge(a, b);
    	return res;
    }
    
    int main() {
    #ifndef ONLINE_JUDGE
    	file("cpp");
    #endif
    	read(n);
    	int ans = 0;
    	for (rg int a, b, x, i = 1; i <= n; ++i) {
    		read(a), read(b);
    		if (a == 0) {
    			if (rt2 == 0) insert(rt1, b);
    			else x = match(rt2, b), erase(rt2, x), ans = (ans + abs(x - b)) % mod;
    		} else {
    			if (rt1 == 0) insert(rt2, b);
    			else x = match(rt1, b), erase(rt1, x), ans = (ans + abs(x - b)) % mod;
    		}
    	}
    	printf("%d
    ", ans);
    	return 0;
    }
    
  • 相关阅读:
    融云使用
    cocoaPods使用
    电脑硬件
    拖图UI和纯代码UI
    7.2内存管理-ARC
    7内存管理-MRC
    数据刷新
    5.1音频播放
    2.6核心动画
    Git常用操作
  • 原文地址:https://www.cnblogs.com/zsbzsb/p/12190645.html
Copyright © 2011-2022 走看看