博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
HDU-3436 Queue-jumpers(Splay树)
阅读量:3760 次
发布时间:2019-05-22

本文共 4108 字,大约阅读时间需要 13 分钟。

传送门:

由于询问只有1e5次,但n<=1e8,因此会有大量没用到的点,将这些点离散一下,单独提取出需要Top操作的点

(吐槽:用通常的splay做法超时了,又换了种写法结果就快了几倍。。。

#include
#define lson l,m,rt<<1#define rson m+1,r,rt<<1|1#define first x#define second y#define eps 1e-8using namespace std;typedef long long LL;typedef pair
PII;const int inf = 0x3f3f3f3f;const int MX = 2e5 + 5;struct Query { char op; int x, id;} que[MX];bool cmp1(Query q1, Query q2) { return q1.x < q2.x;}bool cmp2(Query q1, Query q2) { return q1.id < q2.id;}int T, n, m, nn;int root;int ch[MX][2], fa[MX];int s[MX], t[MX];int sz[MX], num[MX];void NewNode(int &rt, int father, int k) { rt = k; fa[rt] = father; ch[rt][0] = ch[rt][1] = 0; sz[rt] = num[rt] = t[rt] - s[rt] + 1;}void PushUP(int rt) { int ls = ch[rt][0], rs = ch[rt][1]; sz[rt] = sz[ls] + sz[rs] + num[rt];}void build(int &rt, int l, int r, int father) { if (l > r) return; int m = (l + r) >> 1; NewNode(rt, father, m); build(ch[rt][0], l, m - 1, rt); build(ch[rt][1], m + 1, r, rt); PushUP(rt);}void init_zero() { ch[0][0] = ch[0][1] = sz[0] = num[0] = fa[0] = 0;}void init() { root = nn = 0; init_zero(); int prex = 0; sort(que + 1, que + m + 1, cmp1); for (int i = 1; i <= m; i++) { if (que[i].op == 'T' && que[i].x != prex) { if (prex + 1 < que[i].x) { s[++nn] = prex + 1; t[nn] = que[i].x - 1; } s[++nn] = que[i].x; t[nn] = que[i].x; prex = que[i].x; } } if (prex < n) { s[++nn] = prex + 1; t[nn] = n; } build(root, 1, nn, 0); PushUP(root);}void Link(int x, int y, int c) { fa[x] = y; ch[y][c] = x;}void Rotate(int x, int c) { //c=0表示左旋,c=1表示右旋 int y = fa[x]; Link(x, fa[y], ch[fa[y]][1] == y); Link(ch[x][c], y, !c); Link(y, x, c); PushUP(y); //y变成x子节点,只要更新y}void Splay(int x, int f) { while (fa[x] != f) { int y = fa[x]; if (fa[y] == f) Rotate(x, ch[y][0] == x); else { int t = ch[fa[y]][0] == y; if (ch[y][t] == x) Rotate(x, !t); else Rotate(y, t); Rotate(x, t); } } PushUP(x); //更新x if (f == 0) root = x;}int Get_Min(int rt) { while (ch[rt][0]) rt = ch[rt][0]; return rt;}void Delete() { if (ch[root][0] == 0 || ch[root][1] == 0) { root = ch[root][0] + ch[root][1];//如果只有一个儿子则把儿子作为根节点 fa[root] = 0; return; } int rmin = Get_Min(ch[root][1]); Splay(rmin, root); ch[ch[root][1]][0] = ch[root][0];//左子树挂在右边最小的节点的左边 fa[ch[root][0]]=ch[root][1]; root = ch[root][1]; //把右边最小的节点作为根节点 fa[root] = 0; PushUP(root);}int B_search(int x) { //二分查找x属于哪一段 int le = 1, re = nn; while (le <= re) { int mid = (le + re) / 2; if (s[mid] <= x && x <= t[mid])return mid; if (x < s[mid])re = mid - 1; else le = mid + 1; } return -1;}//将点x放到最前面void Top(int x) { int rt = B_search(x); Splay(rt, 0); Delete(); //删掉第x个点 Splay(Get_Min(root), 0);//得到最左边的点 ch[rt][0] = 0; ch[rt][1] = root; //将第x个点放在第一个点前面 fa[root] = rt; root = rt; fa[root] = 0; PushUP(root);}int Query(int x) { int rt = B_search(x); Splay(rt, 0); return sz[ch[root][0]] + x - s[rt] + 1;}int Get_Rank(int rt, int k) { int t = sz[ch[rt][0]]; if (k <= t)return Get_Rank(ch[rt][0], k); else if (k <= t + num[rt]) return s[rt] + k - t - 1; else return Get_Rank(ch[rt][1], k - t - num[rt]);}int main() { //freopen("in.txt", "r", stdin); scanf("%d", &T); int cas = 0; while (T--) { printf("Case %d:\n", ++cas); scanf("%d%d", &n, &m); char op[10]; for (int i = 1, x; i <= m; i++) { scanf("%s%d", op, &x); que[i].op = op[0]; que[i].x = x; que[i].id = i; } init(); sort(que + 1, que + m + 1, cmp2); for (int i = 1; i <= m; i++) { if (que[i].op == 'T') Top(que[i].x); else if (que[i].op == 'R') printf("%d\n", Get_Rank(root, que[i].x)); else printf("%d\n", Query(que[i].x)); } } return 0;}

转载地址:http://npwpn.baihongyu.com/

你可能感兴趣的文章
Ubuntu 创建/删除虚拟环境
查看>>
deepsort算法中绘制轨迹部分的代码【记录】
查看>>
C++程序设计作业--坦克大战[分享]
查看>>
Uuntu20.04出现“qt.qpa.plugin: Could not load the Qt platform plugin “xcb“ in...已放弃 (核心已转储)”问题解决记录
查看>>
linux系统下,使用git clone拉取github上的仓库太慢、卡住问题解决【记录】
查看>>
Linux系统常用的基本操作记录
查看>>
ZeroDivisionError: integer division or modulo by zero解决记录
查看>>
“数据增强”学习记录
查看>>
使用软链接放置数据集
查看>>
TypeError: can‘t convert cuda:0 device type tensor to numpy. 解决记录
查看>>
在一个二维数组中查找整数【python实现】
查看>>
进程、线程、协程的联系与区别
查看>>
OSI的七层模型及其各自的功能
查看>>
关系型和非关系型数据库
查看>>
堆和栈的区别
查看>>
指针常量&常量指针
查看>>
MySQL执行一条SQL的具体步骤及内部构造
查看>>
Exception: Dataset not found.解决记录
查看>>
HTTPS是如何保证数据传输的安全,整体的流程是什么?(SSL是怎么工作保证安全的)
查看>>
TypeError: check_anchors() missing 1 required positional argument: ‘model‘解决记录
查看>>