486E. LIS of Sequence

E. LIS of Sequence

Description

输入 n(1≤n≤1e5) 和长为 n 的数组 a(1≤a[i]≤1e5)。

定义 LIS 为 a 的最长严格递增子序列,注意可能有多个 LIS。
对于每个 i:
如果 a[i] 不在任何 LIS 中,输出 1。
如果 a[i] 在至少一个 LIS 中,但不在所有 LIS 中,输出 2。
如果 a[i] 在所有 LIS 中,输出 3。
输出在同一行,不要加空格。

注意,a=[1,2,2,3] 有两个相同的 LIS [1,2,3],其中 1 和 3 都在这两个 LIS 中,但 2 只在其中一个 LIS 不在另一个 LIS 中,所以输出 3223。

Hints/Notes

  • binary research to solve LIS

Solution

Language: C++

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
#include <iostream>
#include <utility>
#include <string>
#include <cstring>
#include <vector>
#include <map>
#include <set>
#include <stack>
#include <queue>
#include <unordered_map>
#include <unordered_set>
#include <algorithm>
#include <numeric>

#include <fstream>

using namespace std;

istream &in = cin;
ostream &out = cout;

int binary_search(vector<int>& LIS, int target) {
int left = 0, right = LIS.size();
while (left < right) {
int mid = (right - left) / 2 + left;
if (LIS[mid] >= target) {
right = mid;
} else {
left = mid + 1;
}
}
return left;
}

void solve(vector<int>& nums) {
vector<int> LIS;
vector<int> dp1;
int longest = 0;
for (int num : nums) {
int targetIndex = binary_search(LIS, num);
if (targetIndex == LIS.size()) {
LIS.push_back(num);
dp1.push_back(LIS.size());
} else {
dp1.push_back(targetIndex + 1);
LIS[targetIndex] = num;
}
longest = max(longest, (int)LIS.size());
}
for (int& num : nums) {
num = -num;
}
LIS.clear();
vector<int> dp2(nums.size(), 0);
for (int i = nums.size() - 1; i >= 0; i--) {
int num = nums[i];
int targetIndex = binary_search(LIS, num);
if (targetIndex == LIS.size()) {
LIS.push_back(num);
dp2[i] = LIS.size();
} else {
dp2[i] = targetIndex + 1;
LIS[targetIndex] = num;
}
}
vector<int> res(nums.size(), 0);
map<int, int> cnt;
for (int i = 0; i < nums.size(); i++) {
if (dp1[i] + dp2[i] - 1 != longest) {
res[i] = 1;
continue;
}
cnt[dp1[i]]++;
}
for (int i = 0; i < nums.size(); i++) {
if (res[i] == 1) {
continue;
} else if (cnt[dp1[i]] > 1) {
res[i] = 2;
} else {
res[i] = 3;
}
}
for (int i = 0; i < res.size(); i++) {
out << res[i];
}
out << endl;
}

int main() {
int n;
in >> n;
vector<int> nums;
for (int t = 1; t <= n; t++) {
int num;
in >> num;
nums.push_back(num);
}
solve(nums);
return 0;
}