NOI 郁闷的出纳员 (Spay树、平衡树操作)
来源:互联网 发布:淘宝热搜关键词 编辑:程序博客网 时间:2024/04/27 03:49
NOI 郁闷的出纳员 (Spay树、平衡树操作)
插入、删除所有小于p值的节点、k值
注意:可能有相同节点,所以用cnt[]记录
#pragma comment(linker, "/STACK:102400000000,102400000000")#include <cstdio>#include <ctime>#include <cstdlib>#include <cstring>#include <queue>#include <string>#include <set>#include <stack>#include <map>#include <cmath>#include <vector>#include <iostream>#include <algorithm>#include <bitset>using namespace std;//LOOP#define FF(i, a, b) for(int i = (a); i < (b); ++i)#define FE(i, a, b) for(int i = (a); i <= (b); ++i)#define FED(i, b, a) for(int i = (b); i>= (a); --i)#define REP(i, N) for(int i = 0; i < (N); ++i)#define CLR(A,value) memset(A,value,sizeof(A))//INPUT#define RI(n) scanf("%d", &n)#define RII(n, m) scanf("%d%d", &n, &m)#define RIII(n, m, k) scanf("%d%d%d", &n, &m, &k)typedef long long LL;typedef vector <int> VI;const int INF = 0x3f3f3f3f;const double eps = 1e-10;const int maxn = 211111;#define ll ch[x][0]#define rr ch[x][1]#define KT (ch[ch[rt][1]][0])int del_cnt;struct SplayStree{ int ch[maxn][2]; int pre[maxn], sz[maxn], cnt[maxn]; int val[maxn]; int rt, tot; void up(int x) { sz[x] = sz[ll] + sz[rr] + cnt[x];///!!! } void Rotate(int x, int f) { int y = pre[x];// down(y); down(x);/// ch[y][!f] = ch[x][f]; pre[ch[x][f]] = y; pre[x] = pre[y]; if (pre[x]) ch[pre[y]][ch[pre[y]][1] == y] = x; ch[x][f] = y; pre[y] = x; up(y);/// } void Splay(int x, int goal) {// down(x);/// while (pre[x] != goal) { if (pre[pre[x]] == goal) Rotate(x, ch[pre[x]][0] == x); else { int y = pre[x], z = pre[y]; int f = ( ch[z][0] == y ); if (ch[y][f] == x) Rotate(x, !f), Rotate(x, f); else Rotate(y, f), Rotate(x, f); } } up(x);/// if (goal == 0) rt = x; } void Init() { ch[0][0] = ch[0][1] = pre[0] = 0; val[0] = sz[0] = 0; rt = tot = 0; } void Newnode(int &x, int v, int f) { x = ++tot; ll = rr = 0; pre[x] = f; val[x] = v; sz[x] = cnt[x] = 1; } void Insert(int &x, int v, int f) { if (!x) { Newnode(x, v, f); Splay(x, 0); return ; } else if (val[x] == v) { cnt[x]++; sz[x]++; Splay(x, 0); return; } else if (val[x] > v) Insert(ll, v, x); else Insert(rr, v, x); up(x); } void Delete(int &x, int v, int f) { if (!x) return ; if (val[x] < v) { del_cnt += sz[ll] + cnt[x]; x = rr; pre[x] = f; Delete(x, v, f); if (!f) rt = x;///!!! } else Delete(ll, v, x); if (x) up(x); } int kth(int x, int k) {// int ss = sz[rr] + cnt[x]; if (k <= sz[rr]) return kth(rr, k); else if (k > sz[rr] + cnt[x]) return kth(ll, k - sz[rr] - cnt[x]); else { Splay(x, 0); return val[x]; } }}sp;int main(){ int n, m, k; int limit, li; li = 0; del_cnt = 0; char op[5]; scanf("%d%d", &n, &limit); sp.Init(); while (n--) { scanf("%s%d", op, &k); if (op[0] == 'I') { if (k >= limit) sp.Insert(sp.rt, k - li, 0); } else if (op[0] == 'A') li += k; else if (op[0] == 'S') { li -= k; if (sp.sz[sp.rt] > 0) sp.Delete(sp.rt, limit - li, 0); } else { if (k <= 0 || k > sp.sz[sp.rt]) printf("-1\n"); else printf("%d\n", sp.kth(sp.rt, k) + li); }// cout << "sz: " << sp.val[sp.rt] << ' ' << sp.sz[sp.rt] << endl; } printf("%d\n", del_cnt); return 0;}
- NOI 郁闷的出纳员 (Spay树、平衡树操作)
- AVL树 郁闷的出纳员 [NOI 2004] [平衡树解法]
- 【NOI2004】郁闷的出纳员 平衡树
- 平衡二叉树SBT(BZOJ1503[NOI2004]郁闷的出纳员)
- [BZOJ1503][NOI2004]郁闷的出纳员(平衡树splay)
- [BZOJ1503][NOI2004]郁闷的出纳员(平衡树splay)
- splay树解决NOI的郁闷的出纳员
- 平衡树(splay treap)(普通平衡树,郁闷的出纳员)
- AVL树的操作——郁闷的出纳员,平衡树解法
- 【NOI 2004】 郁闷的出纳员
- [NOI 2004]郁闷的出纳员
- [NOI 2004]郁闷的出纳员
- [noi 2004] 郁闷的出纳员
- NOI 2004 郁闷的出纳员
- [NOI 2004] 郁闷的出纳员
- 【NOI2004T1】郁闷的出纳员-平衡树入门题
- 【平衡树】BZOJ1503(NOI2004)[郁闷的出纳员]题解
- 【BZOJ】1503 [NOI2004]郁闷的出纳员 平衡树
- Android绘制几何图形
- SQL语句中 IN 的用法
- redhat 添加DVD作为yum本地源
- win7系统服务
- CDN/P2P/Mediastream 相关的资料搜集分析
- NOI 郁闷的出纳员 (Spay树、平衡树操作)
- 关于UISlider
- Python中的getattr()函数详解
- View工作原理之触摸消息派发过程
- ns2 加入gdb之后make出错
- win7用了安全模式重启后 无线网提示 “有限的访问权限”
- 计算机网络基础--计算机网络和因特网
- 重回微信公众号开发!
- 常用的dos命令