1343F - Restore the Permutation by Sorted Segments

给$r\in [2,n]$,但是$l$随机,区间长度大于$1$,并且将区间的数排好序。随机给出来。

构造出一个排列,符合条件。

枚举第一位,第一位确定了之后找长度$\leq 2$包含第一位的区间,剩下就是第二位,然后继续找长度$\leq 3$包含第一位或者第二位的区间。

这样朴素的算法是$O(n^4)$的,我们每次把找到的元素去除掉,然后去找$set.size=1$的$set$。即可$O(n^3\log n)$,然后为了以防万一。最后再验证乱搞下即可。

代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110

#include <bits/stdc++.h>
#include <set>
using namespace std;
typedef long long ll;
#define pii pair<int, int>
#define mk make_pair
const int N = 2e5 + 10;
const int mod = 1e9 + 7;

int read()
{
int x = 0, f = 1;
char c = getchar();
while (c < '0' || c > '9')
{
if (c == '-')
f = -1;
c = getchar();
}
while (c >= '0' && c <= '9')
x = (x << 1) + (x << 3) + c - '0', c = getchar();
return x * f;
}
int p[N];
int ans[N];
const int SEN = 2e5 + 10;
int a[N], b[N];
struct segmentTree
{

pii sum[SEN << 2];

void pushup(int pos)
{
sum[pos] = min(sum[pos << 1 | 1], sum[pos << 1]);
}
pii query(int ql, int qr, int pos, int l, int r)
{
if (ql <= l && r <= qr)
{
return sum[pos];
}
//pushdown(pos, l, r);
int mid = (l + r) >> 1;
pii ans = mk(1e9, 0);
if (ql <= mid)
ans = min(ans, query(ql, qr, pos << 1, l, mid));
if (qr > mid)
ans = min(ans, query(ql, qr, pos << 1 | 1, mid + 1, r));
return ans;
}
void build(int pos, int l, int r)
{
sum[pos].first = 1e9;
if (l == r)
{
sum[pos].first = a[p[l]];
sum[pos].second = l;
return;
}
int mid = (l + r) >> 1;
build(pos << 1, l, mid);
build(pos << 1 | 1, mid + 1, r);
pushup(pos);
}
} T;

vector<pii> l[N];

int main()
{
int n = read();
for (int i = 1; i <= n; i++)
{
a[i] = read(), b[i] = read();
l[a[i]].push_back(mk(b[i], i));
}
set<pii> s;
for (int i = 1; i <= n; i++)
{
s.insert(l[i].begin(), l[i].end());
ans[s.begin()->second] = i;
p[i] = s.begin()->second;
s.erase(s.begin());
}
T.build(1, 1, n);
for (int i = 1; i <= n; i++)
{
pii k = T.query(ans[i] + 1, b[i], 1, 1, n);
//cout << k.first << " " << k.second << endl;

if (k.first <= ans[i])
{

printf("NO\n");
for (int j = 1; j <= n; j++)
printf("%d ", ans[j]);
puts("");
swap(ans[i], ans[p[k.second]]);
for (int j = 1; j <= n; j++)
printf("%d ", ans[j]);
return 0;
}
}
printf("YES\n");
for (int j = 1; j <= n; j++)
printf("%d ", ans[j]);
puts("");
}