BZOJ1503 [NOI2004]郁闷的出纳员

SPLAY题 4个操作

I 加入一个人,直接插就好了,////!!!!如果新来的人工资小于工资下界,那么他就会立刻离开,这个人是不加到最后离开公司人总数的,就是这里错了,一直找不到

A add 懒标记,在那些往下推的过程中pushdown一下,///这些过程例如说是,getk,Find,Ins等

S 这个减工资,先把这个sub+min插入到树里,然后放到根上,然后把左子树都删掉,再把加入的这个数删去,然后在add -k

F 查询第k大,查询第n-k+1小

 

//PS:最近写了不少这个,虽然神题没做几个,但是就先放一放了,该学点别的去了。

//几个splay注意的地方吧

//1、如果有重复权值的话,给每个点开一个cnt域把,cnt[x]表示,x这个节点 “里面”有几个值

//2、如果是维护序列的话,把下标当关键字插入就好,最好多加入两个节点,最前面一个,最后面一个,这样求前驱和后继就不用特判,很好用

//3、维护数列,建树的时候千万记得每次放入一个,更新root

//4、splay和rota可以模板,就是pushup改一下

//5、pushdown的话,就和线段树差不多啦

 

 

  1 /**************************************************************
  2     Problem: 1503
  3     User: round_0
  4     Language: C++
  5     Result: Accepted
  6     Time:1164 ms
  7     Memory:6820 kb
  8 ****************************************************************/
  9  
 10 #include <cstdio>
 11 #include <cstring>
 12 #include <algorithm>
 13 using namespace std;
 14 typedef long long LL;
 15 const int maxn = 220005;
 16 int fa[maxn],son[2][maxn],val[maxn],siz[maxn],cnt[maxn],add[maxn];
 17 int tot,root,CNT;
 18 void pushup(int x){
 19     siz[x] = siz[son[0][x]]+siz[son[1][x]]+cnt[x];
 20 }
 21 void pushdown(int x){
 22     int l = son[0][x],r = son[1][x];
 23     if(add[x]){
 24         if(l)val[l]+=add[x];
 25         if(r)val[r]+=add[x];
 26         if(l)add[l]+=add[x];
 27         if(r)add[r]+=add[x];
 28         add[x] = 0;
 29     }
 30 }
 31 void rota(int w,int x){
 32     int y = fa[x];
 33     son[!w][y] = son[w][x];
 34     if(son[w][x])fa[son[w][x]] = y;
 35     fa[x] = fa[y];
 36     if(fa[y])son[y==son[1][fa[y]]][fa[y]] = x;
 37     fa[y] = x;
 38     son[w][x] = y;
 39     pushup(y);pushup(x);
 40 }
 41 void splay(int x,int y){
 42     while(fa[x]!=y){
 43         if(fa[fa[x]]==y)rota(x==son[0][fa[x]],x);
 44         else {
 45             int w = fa[x]==son[0][fa[fa[x]]];
 46             if(x==son[w][fa[x]]){
 47                 rota(!w,x);rota(w,x);
 48             }
 49             else {
 50                 rota(w,fa[x]);rota(w,x);
 51             }
 52         }
 53     }
 54     if(y==0)root = x;
 55 }
 56 void Ins(int v){
 57     int x = root;
 58     while(1){
 59         pushdown(x);
 60         siz[x]++;
 61         if(v==val[x]){cnt[x]++;splay(x,0);return;}
 62         if(v<val[x]){
 63             if(son[0][x])x = son[0][x];
 64             else break;
 65         }
 66         else {
 67             if(son[1][x])x = son[1][x];
 68             else break;
 69         }
 70     }
 71     fa[++tot] = x;
 72     val[tot] = v;
 73     siz[tot] = cnt[tot] = 1;
 74     if(v<val[x])son[0][x] = tot;///here
 75     else son[1][x] = tot;
 76     splay(tot,0);
 77 }
 78 int getk(int k){
 79     int x = root;
 80     while(1){
 81         pushdown(x);
 82         if(k>siz[son[0][x]]&&k<=siz[son[0][x]]+cnt[x])return val[x];
 83         if(k<=siz[son[0][x]])x = son[0][x];
 84         else {
 85             k-=(siz[son[0][x]]+cnt[x]);
 86             x = son[1][x];
 87         }
 88     }
 89 }
 90 int Find(int v){
 91     int x = root;
 92     while(1){
 93         pushdown(x);
 94         if(v==val[x])return x;
 95         if(v<val[x])x = son[0][x];
 96         else x = son[1][x];
 97     }
 98 }
 99 void Del(int v){
100     int x = Find(v);
101     splay(x,0);
102     if(cnt[x]>1){cnt[x]--;siz[x]--;return;}
103     int y = son[0][x],z = son[1][x];
104     if(y==0&&z==0){root = 0;return;}
105     while(son[1][y])y = son[1][y];
106     while(son[0][z])z = son[0][z];
107     if(y)splay(y,0);
108     if(z)splay(z,y);
109     if(y==0){son[0][z] = 0;siz[z]--;return;}
110     if(z==0){son[1][y] = 0;siz[y]--;return;}
111     siz[z]--;siz[y]--;son[0][z] = 0;
112 }
113 int main()
114 {
115 //    freopen("in.txt","r",stdin);
116 //    freopen("out2.txt","w",stdout);
117     int n,m;scanf("%d%d",&n,&m);
118     char s[2];int k,ans = 0;
119     for(int i = 1;i<=n;++i){
120         scanf("%s%d",s,&k);
121         if(s[0]=='I'){
122             if(k<m){continue;}
123             if(CNT==0){
124                 root = ++tot;
125                 siz[tot] = 1;
126                 cnt[tot] = 1;
127                 val[tot] = k;
128             }
129             else Ins(k);
130             CNT++;
131         }
132         else if(s[0]=='A'){
133             if(CNT==0)continue;
134             add[root]+=k;
135             val[root]+=k;
136         }
137         else if(s[0]=='S'){
138             if(CNT==0)continue;
139             Ins(m+k);
140             int t = siz[son[0][root]];
141             son[0][root] = 0;
142             siz[root]-=t;
143             ans+=t;
144             CNT-=t;
145             Del(m+k);
146             add[root]-=k;
147             val[root]-=k;
148         }
149         else {
150             if(k>CNT)printf("-1\n");
151             else printf("%d\n",getk(CNT-k+1));
152         }
153     }
154     printf("%d\n",ans);
155     return 0;
156 }

 

posted on 2015-08-11 22:07  round_0  阅读(126)  评论(0编辑  收藏  举报

导航