zoukankan      html  css  js  c++  java
  • _bzoj1503 [NOI2004]郁闷的出纳员【Splay】

    传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=1503

    由于初始工资未达到下限而离开的员工不算在离开人数之内。。。坑爹。。。

    然后就是写kth的时候,忘记考虑当前节点的值有可能出现了不止一次。。。

    #include <cstdio>
    
    const int maxn = 100005;
    
    int n, min_salary, zengL, root, cnt = 1, t1, leave;
    int ch[maxn][2], fa[maxn], siz[maxn], key[maxn], tm[maxn];
    char opr;
    
    inline void pushup(int x) {
    	siz[x] = siz[ch[x][0]] + siz[ch[x][1]] + tm[x];
    }
    inline void rotate(int x) {
    	int y = fa[x];
    	if (y == ch[fa[y]][0]) {
    		ch[fa[y]][0] = x;
    	}
    	else {
    		ch[fa[y]][1] = x;
    	}
    	fa[x] = fa[y];
    	int dir = x == ch[y][1];
    	ch[y][dir] = ch[x][dir ^ 1];
    	fa[ch[x][dir ^ 1]] = y;
    	ch[x][dir ^ 1] = y;
    	fa[y] = x;
    	pushup(y);
    	pushup(x);
    }
    inline void splay(int x) {
    	int p;
    	char flag1, flag2;
    	while (fa[x]) {
    		p = fa[x];
    		if (!fa[p]) {
    			rotate(x);
    		}
    		else {
    			flag1 = p == ch[fa[p]][1];
    			flag2 = x == ch[p][1];
    			if (flag1 ^ flag2) {
    				rotate(x);
    			}
    			else {
    				rotate(p);
    			}
    			rotate(x);
    		}
    	}
    	root = x;
    }
    inline int houji(int val) {
    	int rt = 0, x = root;
    	while (x && val != key[x] + zengL) {
    		if (val < key[x] + zengL) {
    			rt = x;
    			x = ch[x][0];
    		}
    		else {
    			x = ch[x][1];
    		}
    	}
    	return x? x: rt;
    }
    bool ist(int x, int val, int p, int dir) {
    	if (!x) {
    		++cnt;
    		key[cnt] = val - zengL;
    		tm[cnt] = 1;
    		siz[cnt] = 1;
    		fa[cnt] = p;
    		ch[p][dir] = cnt;
    		return true;
    	}
    	if (val == key[x] + zengL) {
    		++tm[x];
    		++siz[x];
    		return false;
    	}
    	int d = val > key[x] + zengL;
    	bool rt = ist(ch[x][d], val, x, d);
    	pushup(x);
    	return rt;
    }
    inline int kth(int k) {
    	int x = root;
    	while (k > siz[ch[x][1]] + tm[x] || k <= siz[ch[x][1]]) {
    		if (k > siz[ch[x][1]] + tm[x]) {
    			k -= siz[ch[x][1]] + tm[x];
    			x = ch[x][0];
    		}
    		else {
    			x = ch[x][1];
    		}
    	}
    	return key[x] + zengL;
    }
    
    int main(void) {
    	//freopen("in.txt", "r", stdin);
    	scanf("%d%d", &n, &min_salary);
    	key[1] = 2000000000;
    	siz[1] = 1;
    	tm[1] = 1;
    	root = 1;
    	while (n--) {
    		while ((opr = getchar()) < 'A');
    		scanf("%d", &t1);
    		if (opr == 'I') {
    			if (t1 >= min_salary && ist(root, t1, 0, 0)) {
    				splay(cnt);
    			}
    		}
    		else if (opr == 'A' || opr == 'S') {
    			zengL += (opr == 'A'? t1: -t1);
    			splay(houji(min_salary));
    			leave += siz[ch[root][0]];
    			ch[root][0] = 0;
    			pushup(root);
    		}
    		else {
    			printf("%d
    ", t1 > siz[root] - 1? -1: kth(t1 + 1));
    		}
    	}
    	printf("%d
    ", leave);
    	return 0;
    }
    

      

  • 相关阅读:
    windows系统历年高危漏洞
    安全产品分类
    防火墙
    UTM(统一威胁管理)
    ORA-39127: 调用 "WMSYS"."LT_EXPORT_PKG"."SCHEMA_INFO_EXP" 时发生意外错误
    oracle如何查看当前有哪些用户连接到数据库
    LINUX修改主机名
    删除Oracle用户及表空间
    Oracle AWR报告详细分析--比较详细
    RMAN优缺点及RMAN备份及恢复步骤
  • 原文地址:https://www.cnblogs.com/ciao-sora/p/6158485.html
Copyright © 2011-2022 走看看