题目地址:http://www.lydsy.com/JudgeOnline/problem.php?id=1503
题目大意:实现5个操作:建立新档案、全局加、全局减、查询K大,当工资低于下界时离开公司。
算法讨论:
下传标记的平衡树,我用的是Treap。
对于“当工资低于下界时离开公司“操作,只需要在查询操作的基础上加一些判断即可。
其余操作和Treap相同。
一题就这样水水地A出了。
Code:
/*
* Problem:1503
* Author:PYC
*/
#include <cstdio>
#include <cstdlib>
#define maxn 100000
#define ll(x) (tree[tree[(x)].l].sz)
#define rr(x) (tree[tree[(x)].r].sz)
using namespace std;
int n,m,tot,root,in;
struct node{
int key,val,l,r,sz,aux,add;
}tree[maxn+1];
void up(int rt){
tree[rt].sz=(tree[rt].l?ll(rt):0)+(tree[rt].r?rr(rt):0)+tree[rt].val;
}
void down(int rt){
if (tree[rt].add){
tree[tree[rt].l].add+=tree[rt].add;
tree[tree[rt].r].add+=tree[rt].add;
tree[tree[rt].l].key+=tree[rt].add;
tree[tree[rt].r].key+=tree[rt].add;
tree[rt].add=0;
}
}
void zig(int &rt){
int t=tree[rt].l;
tree[rt].l=tree[t].r;
tree[t].r=rt;
up(rt);
up(t);
rt=t;
}
void zag(int &rt){
int t=tree[rt].r;
tree[rt].r=tree[t].l;
tree[t].l=rt;
up(rt);
up(t);
rt=t;
}
void insert(int &rt,int y){
if (!rt){
rt=++tot;
tree[rt].key=y;
tree[rt].aux=rand()*rand();
tree[rt].val=tree[rt].sz=1;
tree[rt].l=tree[rt].r=0;
return;
}
down(rt);
if (y==tree[rt].key){
tree[rt].val++;
tree[rt].sz++;
return;
}
if (y<tree[rt].key){
insert(tree[rt].l,y);
tree[rt].sz++;
if (tree[rt].aux>tree[tree[rt].l].aux) zig(rt);
return;
}
if (y>tree[rt].key){
insert(tree[rt].r,y);
tree[rt].sz++;
if (tree[rt].aux>tree[tree[rt].r].aux) zag(rt);
return;
}
}
void find(int &rt){
if (!rt) return;
down(rt);
if (tree[rt].key<m){
rt=tree[rt].r;
find(rt);
return;
}
if (tree[rt].key>=m){
find(tree[rt].l);
up(rt);
return;
}
}
int kth(int &rt,int y){
if (!rt) return 0;
down(rt);
if (y>=rr(rt)+1 && y<=rr(rt)+tree[rt].val) return tree[rt].key;
if (y<rr(rt)+1) return kth(tree[rt].r,y);
if (y>rr(rt)+tree[rt].val) return kth(tree[rt].l,y-rr(rt)-tree[rt].val);
}
int main(){
srand(0);
scanf("%d%d",&n,&m);
for (int i=1;i<=n;++i){
char ch=getchar();
while (ch!='I' && ch!='A' && ch!='S' && ch!='F') ch=getchar();
int y;
scanf("%d",&y);
if (ch=='I'){
if (y>=m){
insert(root,y);
in++;
}
continue;
}
if (ch=='A'){
tree[root].key+=y;
tree[root].add+=y;
continue;
}
if (ch=='S'){
tree[root].key-=y;
tree[root].add-=y;
find(root);
continue;
}
if (ch=='F'){
if (y>tree[root].sz) printf("-1\n");
else printf("%d\n",kth(root,y));
continue;
}
}
printf("%d\n",in-tree[root].sz);
return 0;
}
By Charlie Pan
Mar 4,2014