1 solutions

  • 2
    @ 2025-4-16 16:53:24

    题意

    不是很难看懂,分类讨论嘛

    思路

    以宠物为例,如果没人领养,那么就把它们放进 Treap1。有人的话(领养人过多),先看看有没有特点值相同的,有的话就直接把那个人从 Treap2 删掉;再找前驱和后继比较,加上差值再把那个人从 Treap2 删掉。人的话也一样。

    代码

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    template<int SIZE = int(1e7) + 5>
    class Treap{
    	private:
    		struct node{
    			int l,r;
    			int k,x;	// k:关键码
    			int cnt,size;	// cnt:个数;size:子树大小
    		}nodes[SIZE];
    		int root,tot,INF = 0x7fffffff;
    		int push(int x){
    			nodes[++tot].k = rand();
    			nodes[tot].x = x;
    			nodes[tot].cnt = 1;
    			nodes[tot].size = 1;
    			return tot;
    		}
    		void upd(int p){
    			nodes[p].size = nodes[nodes[p].l].size + nodes[nodes[p].r].size + nodes[p].cnt;
    		}
    		void ins(int &p,int x){
    			if (!p){
    				p = push(x);	// nodes[fa].l(或r)= p
    				return ;
    			}
    			nodes[p].size++;
    			if (x == nodes[p].x){
    				nodes[p].cnt++;
    				return ;
    			}
    			if (x < nodes[p].x){
    				ins(nodes[p].l,x);
    				if (nodes[p].k < nodes[nodes[p].l].k)	zig(p);
    			}else{
    				ins(nodes[p].r,x);
    				if (nodes[p].k < nodes[nodes[p].r].k)	zag(p);
    			}
    		}
    		void rm(int &p,int x){
    			if (!p)	return ;
    			nodes[p].size--;
    			if (x == nodes[p].x){
    				if (nodes[p].cnt > 1){
    					nodes[p].cnt--;
    					return ;
    				}
    				if (!(nodes[p].l && nodes[p].r))	p = nodes[p].l + nodes[p].r;
    				else if (nodes[nodes[p].l].k > nodes[nodes[p].r].k){
    					zig(p);
    					rm(nodes[p].r,x);
    				}else{
    					zag(p);
    					rm(nodes[p].l,x);
    				}
    				return ;
    			}
    			if (x < nodes[p].x)	rm(nodes[p].l,x);
    			else	rm(nodes[p].r,x);
    		}
    		int v2r(int p,int x){
    			if (!p)	return -INF;
    			if (x == nodes[p].x)	return nodes[nodes[p].l].size + 1;
    			if (x < nodes[p].x)	return v2r(nodes[p].l,x);
    			return v2r(nodes[p].r,x) + nodes[nodes[p].l].size + nodes[p].cnt;
    		}
    		int r2v(int p,int r){
    			if (!p)	return 0;
    			if (nodes[nodes[p].l].size >= r)	return r2v(nodes[p].l,r);
    			if (nodes[nodes[p].l].size + nodes[p].cnt >= r)	return nodes[p].x;
    			return r2v(nodes[p].r,r - nodes[nodes[p].l].size - nodes[p].cnt);
    		}
    	public:
    		void zig(int &p){	// 右旋
    			int q = nodes[p].l;
    			nodes[p].l = nodes[q].r,
    			nodes[q].r = p,
    			nodes[q].size = nodes[p].size;
    			upd(p);
    			p = q;
    		}
    		void zag(int &p){	// 左旋
    			int q = nodes[p].r;
    			nodes[p].r = nodes[q].l,
    			nodes[q].l = p,
    			nodes[q].size = nodes[p].size;
    			upd(p);
    			p = q;
    		}
    		void ins(int x){
    			ins(root,x);
    		}
    		void rm(int x){
    			rm(root,x);
    		}
    		int pre(int x){
    			int p = root;
    			int res = -INF;
    			while (p){
    				if (nodes[p].x < x)	res = nodes[p].x,p = nodes[p].r;
    				else	p = nodes[p].l;
    			}
    			return res;
    		}
    		int nxt(int x){
    			int p = root;
    			int res = INF;
    			while (p){
    				if (nodes[p].x > x)	res = nodes[p].x,p = nodes[p].l;
    				else	p = nodes[p].r;
    			}
    			return res;
    		}
    		int find(int x){	// 返回值x的排名(定义为比x小的数的个数+1)
    			return v2r(root,x);
    		}
    		int get(int r){	// 返回排名r的值
    			return r2v(root,r);
    		}
    		int size(){
    			return nodes[root].size;
    		}
    };
    const int N = 8e4 + 5,INF = 0x7fffffff,MOD = 1e6;
    Treap<N> l,c;	// 领养者,宠物
    ll sum;
    int main(int argc, char **argv){
    	int n;
    	cin >> n;
    	for (int i = 1;i <= n;i++){
    		bool op;int x;
    		cin >> op >> x;
    		if (op){
    			if (!c.size())	l.ins(x);
    			else{
    				ll pre = c.pre(x),nxt = c.nxt(x);
    				if (pre == -INF && nxt == INF)	continue;
    				if (c.find(x) > 0)
    					c.rm(x);
    				else if (x - pre <= nxt - x){
    					sum += x - pre;
    					c.rm(pre);
    				}else{
    					sum += nxt - x;
    					c.rm(nxt);
    				}
    			}
    		}else{
    			if (!l.size())	c.ins(x);
    			else{
    				ll pre = l.pre(x),nxt = l.nxt(x);
    				if (pre == -INF && nxt == INF)	continue;
    				if (l.find(x) > 0)
    					l.rm(x);
    				else if (x - pre <= nxt - x){
    					sum += x - pre;
    					l.rm(pre);
    				}else{
    					sum += nxt - x;
    					l.rm(nxt);
    				}
    			}
    		}
    		sum %= MOD;
    		// printf(" %lld\n",sum);
    	}
    	cout << sum;
    	return 0;
    }
    
    • 1

    Information

    ID
    146
    Time
    1000ms
    Memory
    512MiB
    Difficulty
    8
    Tags
    # Submissions
    31
    Accepted
    5
    Uploaded By