首页 > 代码库 > cf 420D. Cup Trick (Splay树)
cf 420D. Cup Trick (Splay树)
Splay 树的比较基本的序列维护操作, 用getSeg( int l, int r) 获取要操作的区间
若:获取区间[l,r],非空,getSeg(l,r),然后KT指向区间[l,r]
若:获取区间为空,如当要在l位置插入一个值时,则getSeg(l,l-2),然后可在KT赋值新节点
D. Cup Trick
#include <iostream> #include <cstdio> #include <cstring> #include <string> #include <cmath> #include <algorithm> #include <cstdlib> #include <vector> using namespace std; #define ll ch[x][0] #define rr ch[x][1] #define KT (ch[ch[rt][1]][0]) const int maxn = 2000100; int vis[maxn], t[maxn]; struct SplayTree{ ///基本数据定义 int ch[maxn][2]; int sz[maxn], pre[maxn]; int rt, tot; ///题目变量 int val[maxn], id[maxn]; ///Splay树的基本旋转操作函数 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 RTO(int k, int goal) { int x = rt; while (sz[ll] + 1 != k) { if (k < sz[ll] + 1) x = ll; else { k -= (sz[ll] + 1); x = rr; } } Splay(x, goal); } ///Splay树的生成函数 void newnode(int &x, int v, int idd, int f)/// { x = ++tot; ll = rr = 0; sz[x] = 1; pre[x] = f; val[x] = v; id[x] = idd; } void build(int &x, int l, int r, int f)/// { if (l > r) return ; int m = (l + r) >> 1; newnode(x, -1, m, f); build(ll, l, m - 1, x); build(rr, m + 1, r, x); up(x); } void Init(int n) { ch[0][0] = ch[0][1] = pre[0] = sz[0] = 0; val[0] = -1; id[0] = 0; rt = tot = 0; newnode(rt, -1, 0, 0); newnode(ch[rt][1], -1, 0, rt); build(KT, 1, n, ch[rt][1]);/// up(ch[rt][1]); up(rt);/// } ///区间操作相关up(), down() void up(int x)///!!! { sz[x] = sz[ll] + sz[rr] + 1;///!!! } void getSeg(int l, int r) { RTO(l, 0); RTO(r + 2, rt); } ///题目函数 bool solve(int q) { int xx, y, z; int fla = 1; for (int i = 0; i < q; i++) { scanf("%d%d", &xx, &y); getSeg(y, y); if (!fla) continue; if (val[KT] != -1 && val[KT] != xx) { fla = 0; continue; } if (vis[xx] && vis[xx] != id[KT]) { fla = 0; continue; } z = id[KT]; KT = 0; up(ch[rt][1]); up(rt); getSeg(1, 0);///区间为0 newnode(KT, xx, z, ch[rt][1]);///??? t[z] = xx; vis[xx] = z; up(ch[rt][1]); up(rt); } return fla; } }sp; int main() { int n, q; while (cin >> n >> q) { memset(vis, 0, sizeof(vis)); memset(t, 0, sizeof(t)); sp.Init(n); if (!sp.solve(q)) { puts("-1"); continue; } int r = 1; for (int i = 1; i <= n; i++) { if (!t[i]) { while (vis[r]) r++; t[i] = r++; } } for (int i = 1; i <= n; i++) { if (i != 1) printf(" "); printf("%d", t[i]); } puts(""); } return 0; }
cf 420D. Cup Trick (Splay树)
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。