zoukankan      html  css  js  c++  java
  • 洛谷 P1486 [NOI2004] 郁闷的出纳员

    Description

    P1486 [NOI2004] 郁闷的出纳员

    Solution

    无旋(treap)(fhq-treap)

    如果有不会 (fhq-treap) 的同学,可以看我的博客 浅谈 fhq-treap(无旋treap)

    下面我们来看一看这道题。

    发现 新建工资档案查询第 (k) 多工资 都是板子。

    那这个整体加和整体减如何处理呢?

    其实很简单。

    我们记录一个变量 (delta) 加上或减去题目中输入的数值就好。

    进行删除操作时,我们把工资小于等于 (mins - delta - 1) 的员工删去即可。

    查询时,输出查出来的工资加上 (delta) 即可。

    注意:题目要求查询第 (k) 多工资,而我们只能查询第 (k) 小,要稍微转换一下,改成查询 (n - k + 1)

    具体看代码吧。

    Code

    #include <bits/stdc++.h>
    #define ls(x) t[x].ch[0]
    #define rs(x) t[x].ch[1]
    
    using namespace std;
    
    const int N = 3e5 + 10;
    struct Treap{
    	int ch[2], siz, val, wei;
    }t[N];
    int n, mins, root, tot, delta, sum;
    int a, b, c;
    
    inline int read(){
    	int x = 0, f = 1;
    	char ch = getchar();
    	while(ch < '0' || ch > '9') {if(ch == '-') f = -1; ch = getchar();}
    	while(ch >= '0' && ch <= '9') x = (x << 3) + (x << 1) + ch - '0', ch = getchar();
    	return x * f;
    }
    
    inline void pushup(int x){
    	t[x].siz = t[ls(x)].siz + t[rs(x)].siz + 1;
    }
    
    inline void split(int x, int k, int &a, int &b){
    	if(!x){
    		a = b = 0;
    		return;
    	}
    	if(t[x].val <= k){
    		a = x;
    		split(rs(x), k, rs(x), b);
    	}else{
    		b = x;
    		split(ls(x), k, a, ls(x));
    	}
    	pushup(x);
    }
    
    inline int merge(int x, int y){
    	if(!x || !y) return x | y;
    	if(t[x].wei <= t[y].wei){
    		rs(x) = merge(rs(x), y);
    		pushup(x);
    		return x;
    	}else{
    		ls(y) = merge(x, ls(y));
    		pushup(y);
    		return y;
    	}
    }
    
    inline int newnode(int k){
    	t[++tot].val = k, t[tot].siz = 1, t[tot].wei = rand();
    	return tot;
    }
    
    inline void insert(int k){
    	split(root, k, a, b);
    	root = merge(a, merge(newnode(k), b));
    }
    
    inline void remove(){
    	split(root, mins - delta - 1, a, b);
    	root = b;
    	sum += t[a].siz;
    }
    
    inline int query_val(int x, int k){
    	if(k == t[ls(x)].siz + 1) return t[x].val;
    	if(k <= t[ls(x)].siz) return query_val(ls(x), k);
    	else return query_val(rs(x), k - t[ls(x)].siz - 1);
    }
    
    int main(){
    	n = read(), mins = read();
    	char op;
    	int x;
    	for(int i = 1; i <= n; i++){
    		cin>>op;
    		x = read();
    		if(op == 'I' && x >= mins) x -= delta, insert(x);
    		if(op == 'A') delta += x;
    		if(op == 'S') delta -= x, remove();
    		if(op == 'F'){
    			if(t[root].siz < x) puts("-1");
    			else printf("%d
    ", query_val(root, t[root].siz - x + 1) + delta);		//注意题目查询第 k 大,就是第 n - k + 1 小
    		}
    	}
    	printf("%d
    ", sum);
    	return 0;
    }
    

    End

    本文来自博客园,作者:xixike,转载请注明原文链接:https://www.cnblogs.com/xixike/p/15153373.html

  • 相关阅读:
    tips for Flask
    REST
    数据结构与算法分析 in C语言
    大学环境对大学生学习心态的影响
    Qpython_文本读写_工作目录
    The Zen of Python
    SQL SERVER数据库中DDL语句
    sql server创建序列sequence
    macbook 安装redis流程及问题总结
    mac系统chrome浏览器快捷键
  • 原文地址:https://www.cnblogs.com/xixike/p/15153373.html
Copyright © 2011-2022 走看看