题解
([l,r]) 的 (mathrm{mex}) 值为 (val) 时, (0,1,cdots,val-1) 位置一定在 ([l,r]) 中 ,(val) 位置一定不在 ([l,r]) 中。
则 (x) 可以选的位置集合 (S(x) = igcaplimits_{val_i = x} overline{[l_i,r_i]} cap igcaplimits_{val_i > x}[l_i,r_i] capmathbf{N}) 。
如果 (S(x) = varnothing) 输出 ( exttt{-1}) 。
从小到大枚举 (x) ,可以用一个数组 (st) 装 (S(x)) 的元素。
考虑 (igcaplimits_{val_i > x}[l_i,r_i] subseteq igcaplimits_{val_i > x+1}[l_i,r_i]) ,也就是说,设 ([L_x,R_x] = igcaplimits_{val_i > x}[l_i,r_i]) ,则 (L_{x+1} leq L_x leq R_x leq R_{x+1}) 。
又想到 (igcaplimits_{val_i = x} overline{[l_i,r_i]}) 是互不交的,所以处理完 (x-1) ,开始处理 (x) 的时候,设 (T = [L_x,L_{x-1}) cap (R_{x-1},R_x] capmathbf{N}) ,先在 (st) 中加入 (T cap overline{igcaplimits_{val_i = x} overline{[l_i,r_i]}}) ,然后在 (st) 中随便选一个元素作为 (x) 的位置,并删去这个元素,再在 (st) 中加入 (T cap igcaplimits_{val_i = x} overline{[l_i,r_i]}) 。注意 (st = varnothing) 的时候输出 ( exttt{-1}) 。总复杂度为 (O(n+m)) 。(具体看代码)
#include <cstdio>
#include <cctype>
#include <algorithm>
#define MAX_N (500000 + 5)
#define MAX_M (500000 + 5)
using std::max;
using std::min;
int n, m;
struct Interval {
int l, r;
} a[MAX_N], b[MAX_N];
int c[MAX_N];
int st[MAX_N], top;
int ans[MAX_N];
int Read() {
int res = 0;
char ch = getchar();
while (!isdigit(ch)) ch = getchar();
while (isdigit(ch)) res = res * 10 + ch - '0', ch = getchar();
return res;
}
int main() {
n = Read(), m = Read();
int l, r, val;
for (int i = 0; i <= n; ++i) {
a[i].l = 0;
a[i].r = n;
b[i].l = n + 1;
b[i].r = -1;
}
for (int i = 1; i <= m; ++i) {
l = Read(), r = Read(), val = Read();
if (val) {
a[val - 1].l = max(a[val - 1].l, l);
a[val - 1].r = min(a[val - 1].r, r);
b[val].l = min(b[val].l, l);
b[val].r = max(b[val].r, r);
if (a[val - 1].l > a[val - 1].r) {
printf("-1");
return 0;
}
}
else {
++c[l];
--c[r + 1];
}
}
bool flag = 0;
for (int i = 0; i <= n; ++i) {
if (i) c[i] += c[i - 1];
if (!c[i]) flag = 1;
}
if (!flag) {
printf("-1");
return 0;
}
for (int i = n - 1; ~i; --i) {
a[i].l = max(a[i].l, a[i + 1].l);
a[i].r = min(a[i].r, a[i + 1].r);
if (a[i].l > a[i].r) {
printf("-1");
return 0;
}
}
for (int i = a[0].l; i <= a[0].r; ++i) {
if (c[i]) continue;
st[++top] = i;
}
if (!top) {
printf("-1");
return 0;
}
ans[st[top--]] = 0;
for (int i = a[0].l; i <= a[0].r; ++i) {
if (!c[i]) continue;
st[++top] = i;
}
for (int i = 1; i <= n; ++i) {
if (b[i].l <= a[i].l && a[i].r <= b[i].r) {
printf("-1");
return 0;
}
for (int j = a[i].l; j < a[i - 1].l; ++j)
if (j < b[i].l || b[i].r < j) st[++top] = j;
for (int j = a[i].r; j > a[i - 1].r; --j)
if (j < b[i].l || b[i].r < j) st[++top] = j;
if (!top) {
printf("-1");
return 0;
}
ans[st[top--]] = i;
for (int j = a[i].l; j < a[i - 1].l; ++j)
if (b[i].l <= j && j <= b[i].r) st[++top] = j;
for (int j = a[i].r; j > a[i - 1].r; --j)
if (b[i].l <= j && j <= b[i].r) st[++top] = j;
}
for (int i = 0; i <= n; ++i)
printf("%d ", ans[i]);
return 0;
}