SPLAY題 4個操做spa
I 加入一我的,直接插就行了,////!!!!若是新來的人工資小於工資下界,那麼他就會馬上離開,這我的是不加到最後離開公司人總數的,就是這裏錯了,一直找不到code
A add 懶標記,在那些往下推的過程當中pushdown一下,///這些過程例如說是,getk,Find,Ins等blog
S 這個減工資,先把這個sub+min插入到樹裏,而後放到根上,而後把左子樹都刪掉,再把加入的這個數刪去,而後在add -kget
F 查詢第k大,查詢第n-k+1小string
//PS:最近寫了很多這個,雖然神題沒作幾個,可是就先放一放了,該學點別的去了。it
//幾個splay注意的地方吧io
//一、若是有重複權值的話,給每一個點開一個cnt域把,cnt[x]表示,x這個節點 「裏面」有幾個值模板
//二、若是是維護序列的話,把下標當關鍵字插入就好,最好多加入兩個節點,最前面一個,最後面一個,這樣求前驅和後繼就不用特判,很好用class
//三、維護數列,建樹的時候千萬記得每次放入一個,更新rootim
//四、splay和rota能夠模板,就是pushup改一下
//五、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 }