NOIP2017 D1T3 列队
来源:互联网 发布:linux读取文件指定行 编辑:程序博客网 时间:2024/06/04 20:03
NOIP2017 D1T3 列队
考场上嘴巴AC最后沦为30暴力选手…加上第一天D1T2神奇的错了两个点…失去生涯最后一次AK机会啦qwq
其实没那么难写qwq
考虑用
一个比较麻烦的事情是如果当前取的元素还没有出过队,需要计算这一行第
由于splay每次操作只会做
#include <bits/stdc++.h>using namespace std;const int MAXN = 5000005;int root[MAXN], lc[MAXN], rc[MAXN], tot = 0, dat[MAXN];void push(int &nd, int pos, int L, int R){ if (!nd) nd = ++tot; dat[nd]++; if (L == R) return; int mid = (L+R)>>1; if (pos <= mid) push(lc[nd], pos, L, mid); else push(rc[nd], pos, mid+1, R);}int find_kth(int nd, int k, int L, int R){ if (L == R) return L; int mid = (L+R)>>1, lcnt = mid-L+1-dat[lc[nd]]; if (k <= lcnt) return find_kth(lc[nd], k, L, mid); else return find_kth(rc[nd], k-lcnt, mid+1, R);}int n, m, q;int remain[MAXN];int chl[MAXN][2], fa[MAXN], siz[MAXN];long long dt[MAXN];int top = 0;struct splay_tree{ int rt; splay_tree() { rt = 0; } inline void update(int nd) { siz[nd] = siz[chl[nd][0]]+siz[chl[nd][1]]+1; } void zig(int nd) { int p = fa[nd], g = fa[p], tp = chl[p][0] != nd, tg = chl[g][0] != p; int son = chl[nd][tp^1]; if (son) fa[son] = p; if (g) chl[g][tg] = nd; else rt = nd; fa[p] = nd, fa[nd] = g, chl[p][tp] = son, chl[nd][tp^1] = p; update(p), update(nd); } void splay(int nd, int tar = 0) { while (fa[nd] != tar) { int p = fa[nd], g = fa[p], tp = chl[p][0] != nd, tg = chl[g][0] != p; if (g == tar) { zig(nd); break; } else if (tp == tg) zig(p), zig(nd); else zig(nd), zig(nd); } } int kth_ele(int k) { int nd = rt; while (1) { if (siz[chl[nd][0]]+1 == k) return splay(nd), nd; else if (k <= siz[chl[nd][0]]+1) nd = chl[nd][0]; else k -= siz[chl[nd][0]]+1, nd = chl[nd][1]; } } long long del_kth(int k) { int nd = kth_ele(k); int pre = chl[nd][0], nxt = chl[nd][1]; while (chl[pre][1]) pre = chl[pre][1]; while (chl[nxt][0]) nxt = chl[nxt][0]; if (!pre && !nxt) rt = 0; else if (!pre) splay(nxt), chl[nxt][0] = 0, update(nxt); else if (!nxt) splay(pre), chl[pre][1] = 0, update(pre); else splay(pre), splay(nxt, pre), chl[nxt][0] = 0, update(nxt), update(pre); return dt[nd]; } void push_last(long long d) { int nd = ++top; dt[nd] = d, update(nd); int pos = rt; if (rt == 0) rt = nd; else if (!chl[rt][1]) chl[rt][1] = nd, fa[nd] = rt, update(rt); else { while (chl[pos][1]) pos = chl[pos][1]; chl[pos][1] = nd, fa[nd] = pos; for (register int i = nd; i; i = fa[i]) update(i); splay(nd); } } void display(int nd, int tab = 0) { for (int i = 1; i <= tab; i++) cerr << " "; if (nd == 0) { cerr << "." << endl; return; } else { cerr << nd << " " << dt[nd] << " " << fa[nd] << " " << siz[nd] << endl; display(chl[nd][0], tab+2), display(chl[nd][1], tab+2); } }} rgt, line[MAXN];int main(){ scanf("%d%d%d", &n, &m, &q); for (int i = 1; i <= n; i++) { rgt.push_last((long long)i*m), remain[i] = m-1; } for (int i = 1; i <= q; i++) { int x, y; scanf("%d%d", &x, &y); if (y == m) { long long d = rgt.del_kth(x); printf("%lld\n", d), rgt.push_last(d); } else if (y <= remain[x]) { int pos = find_kth(root[x], y, 1, m-1); long long id = (long long)(x-1)*m+pos; printf("%lld\n", id); remain[x]--, push(root[x], pos, 1, m-1); long long p = rgt.del_kth(x); line[x].push_last(p), rgt.push_last(id); } else { y -= remain[x]; long long id = line[x].del_kth(y), p = rgt.del_kth(x); printf("%lld\n", id), line[x].push_last(p), rgt.push_last(id); } } return 0;}
阅读全文
0 0
- NOIP2017 D1T3 列队
- [noip2017 D1T3]逛公园
- NOIP2017 D1T3 逛公园
- NOIP2017 Day2_T3 列队
- 洛谷P3960 [NOIp2017]列队
- NOIP2017 D2T3 列队
- [noip2017]列队 splay
- jzoj5478. 【NOIP2017提高组】列队
- NOIP2017提高组D2T3[列队]
- NOIP2017提高组D1T3[逛公园]
- 【NOIP2017提高组正式赛】列队
- 【NOIP2017提高组正式赛】D2T3列队
- 5478. 【NOIP2017提高组正式赛】列队
- 「NOIP2017」列队 //线段树
- NOIP2017 列队 题解报告【56行线段树】
- JZOJ 5478. 【NOIP2017提高组正式赛】列队
- NOIP2017 列队 线段树(指针版)+vector
- 【NOIP2017DAY2T3 【NOIP2017提高组正式赛】列队 】(动态开点+n棵线段树)
- Linux系统编译VLC-Android
- 求二维数组元素和的4种等价方式(利用二维数组和指针)
- 修改Linux系统主机名
- java简单的基础轮廓
- stm32_018_stm32自身唯一ID读取
- NOIP2017 D1T3 列队
- Java 五种类实例化的方法与初始化顺序
- 初学者---Android 一款好用的Dialog开源框架NiftyDialogEffects
- MSP430G2553 串口通信
- 【BZOJ】4403 序列统计 Lucas
- 筛法求素数
- AngularJS排序查询以及添加
- C++ class 总结
- [知了堂学习笔记] JQuery对DOM的操作