洛谷 P1486 BZOJ 1503 NOI 2004 鬱悶的出納員 fhq treap

思路:node

1. 此處的fhq treap的分裂是按照權值分裂而後插入的。將小於k的分爲一棵子樹,大於等於k的分爲另外一棵子樹。c++

2. 刪除的時候只要將大於等於min的分裂到以root爲根的樹中,另外一部分不用管,扔掉。ide

3. 維護一個加標記,注意不要忘記某個地方的pushdown和pushupspa

其餘就是fhq treap的基本操做了code

#include<bits/stdc++.h>
using namespace std; #define ls a[x].l
#define rs a[x].r
const int N = 1e5 + 10; int root, tot, ans; struct tree{ int l, r, atag, val, dat, siz; }a[N]; struct fhq_treap{ void newnode(int &x, int val){ a[x = ++tot].dat = rand(); a[x].siz = 1; a[x].val = val; } void addone(int x, int val){ if(!x) return; a[x].val += val; a[x].atag += val; } void up(int x){ if(!x) return ; a[x].siz = a[ls].siz + a[rs].siz + 1; } void down(int x){ if(!x) return; if(a[x].atag) addone(ls, a[x].atag), addone(rs, a[x].atag); a[x].atag = 0; } void Merge(int &x, int l, int r){ if(!l || !r) x = l + r; else if(a[l].dat < a[r].dat) down(x = l), Merge(rs, rs, r), up(x); else down(x = r), Merge(ls, l, ls), up(x); } void split(int x, int k, int &l, int &r){ if(!x) l = r = 0; else{ down(x); if(a[x].val < k) l = x, split(rs, k, rs, r); else r = x, split(ls, k, l, ls); } up(x); } void ins(int val){ int x; newnode(x, val); int l, r; split(root, val, l, r); Merge(l, l, x); Merge(root, l, r); } int getval(int x, int rank){ if(x == 0) return -1; down(x); if(a[rs].siz >= rank) return getval(rs, rank); if(a[rs].siz + 1 >= rank) return a[x].val; return getval(ls, rank - a[rs].siz - 1); } void del(int val){ int l; split(root, val, l, root); } }treap; int n, lim, k; char ch[5]; int main(){ scanf("%d%d", &n, &lim); while(n--){ scanf("%s%d", ch, &k); if(ch[0] == 'I'){ if(k >= lim) treap.ins(k), ans++; } else if(ch[0] == 'A') treap.addone(root, k); else if(ch[0] == 'S') treap.addone(root, -k), treap.del(lim); else printf("%d\n", treap.getval(root, k)); } printf("%d\n", ans - a[root].siz); return 0; }
View Code
相關文章
相關標籤/搜索