Splay 树的比较基本的序列维护操作, 用getSeg( int l, int r) 获取要操作的区间
若:获取区间[l,r],非空,getSeg(l,r),然后KT指向区间[l,r]
若:获取区间为空,如当要在l位置插入一个值时,则getSeg(l,l-2),然后可在KT赋值新节点
#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;
}