zoukankan      html  css  js  c++  java
  • 【BZOJ 1503】【NOI 2004】郁闷的出纳员

    $Splay$模板题。

    复习一下伸展树的模板。

    一定不要忘了push啊!!!

    对于减工资后删掉员工的操作,我选择插入一个$min+delta_{减少的工资}$的节点,把它$Splay$到根,砍掉它自己和左子树,保留右子树,这样该走的员工就会从这个世界上消失啦~~~

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #define read(x) x = getint()
    using namespace std;
    struct node {
    	node *ch[2], *fa;
    	int d, sz, sum, lazy;
    	bool pl() {return this->fa->ch[1] == this;}
    	void setc(node *r, bool c) {ch[c] = r; r->fa = this;}
    	void count() {sum = ch[0]->sum + ch[1]->sum + sz;}
    	void push() {
    		if (lazy != 0) {
    			ch[0]->lazy += lazy;
    			ch[1]->lazy += lazy;
    			ch[0]->d += lazy;
    			ch[1]->d += lazy;
    			lazy = 0;
    		}
    	}
    }*ROOT, *null;
    node pool[100003];
    int top = 0, M, n, gone = 0;
    namespace Splay{
    	void Build() {
    		null = &pool[0];
    		null->d = null->sz = null->sum = 0;
    		null->ch[0] = null->ch[1] = null->fa = null;
    		ROOT = null;
    	}
    	node *newnode() {
    		node *t = &pool[++top];
    		t->d = t->sz = t->sum = 0;
    		t->ch[0] = t->ch[1] = t->fa = null;
    		return t;
    	}
    	void rotate(node *r) {
    		node *f = r->fa; if (r == null || f == null) return;
    		bool c = r->pl();
    		if (f->fa == null) ROOT = r, r->fa = null;
    		else f->fa->setc(r, f->pl());
    		f->setc(r->ch[!c], c);
    		r->setc(f, !c);
    		f->count();
    	}
    	void update(node *r) {if (r != ROOT) update(r->fa);	r->push();}
    	void splay(node *r, node *tar = null) {
    		update(r);
    		for(; r->fa != tar; rotate(r))
    			if (r->fa->fa != tar) rotate(r->pl() == r->fa->pl() ? r->fa : r);
    		r->count();
    	}
    	void ins(int num) {
    		if (ROOT == null) {
    			ROOT = newnode();
    			ROOT->d = num;
    			ROOT->sz = ROOT->sum = 1;
    			return;
    		}
    		node *r = ROOT;
    		while (1) {
    			r->push();
    			int k = r->d; bool c;
    			if (num < k) c = 0;
    			else if (num > k) c = 1;
    			else {++r->sz; ++r->sum; splay(r); return;}
    			if (r->ch[c] == null) {
    				r->ch[c] = newnode();
    				r->setc(r->ch[c], c);
    				r->ch[c]->sz = r->ch[c]->sum = 1;
    				r->ch[c]->d = num;
    				splay(r->ch[c]);
    				return;
    			} else r = r->ch[c];
    		}
    	}
    	void ins2(int num) {
    		node *r = ROOT;	bool c;
    		while (1) {
    			r->push();
    			if (num <= r->d) c = 0;
    			else c = 1;
    			if (r->ch[c] == null) {
    				r->ch[c] = newnode();
    				r->setc(r->ch[c], c);
    				splay(r->ch[c]);
    				gone += ROOT->ch[0]->sum;
    				ROOT->ch[1]->fa = null;
    				ROOT = ROOT->ch[1];
    				return;
    			} else r = r->ch[c];
    		}
    	}
    	int kth(int k) {
    		node *r = ROOT;
    		while (r != null) {
    			r->push();
    			if (r->ch[1]->sum >= k) r = r->ch[1];
    			else if (r->ch[1]->sum + r->sz >= k) return r->d;
    			else k -= r->ch[1]->sum + r->sz, r = r->ch[0];
    		}
    		return 0;
    	}
    }
    
    inline int getint() {
    	int k = 0, fh = 1; char c = getchar();
    	for(; c < '0' || c > '9'; c = getchar())
    		if (c == '-') fh = -1;
    	for(; c >= '0' && c <= '9'; c = getchar())
    		k = k * 10 + c - '0';
    	return k * fh;
    }
    int main() {
    	Splay::Build();
    	read(n); read(M);
    	int num;
    	for(int i = 1; i <= n; ++i) {
    		char c = getchar();	while (c < 'A' || c > 'Z') c = getchar();
    		switch (c) {
    			case 'I':
    				read(num);
    				if (num >= M)
    					Splay::ins(num);
    			break;
    			case 'A':
    				read(num);
    				ROOT->d += num;
    				ROOT->lazy += num;
    				ROOT->push();
    			break;
    			case 'S':
    				read(num);
    				Splay::ins2(num + M);
    				ROOT->d -= num;
    				ROOT->lazy -= num;
    				ROOT->push();
    			break;
    			case 'F':
    				read(num);
    				if (num > ROOT->sum) puts("-1");
    				else printf("%d
    ", Splay::kth(num));
    			break;
    		}
    	}
    	printf("%d
    ", gone);
    	return 0;
    }
    

      

  • 相关阅读:
    except与besides
    think用法
    walk用法
    complain用法
    go through用法
    herd用法
    ridiculous用法
    it is the same as用法
    let us say用法
    1002 A+B for Polynomials (25 分)(模拟)
  • 原文地址:https://www.cnblogs.com/abclzr/p/5349485.html
Copyright © 2011-2022 走看看