比赛的时候,用线段树做的。之后发现,这题就是一个裸的最长下降子序列的题目。主要难点是它的n的范围是1e6,要优化为nlogn级别。
#include <bits/stdc++.h>
#define inf 0x3f3f3f3f
using namespace std;
typedef long long LL;
const int N = 1e6 + 10;
int n, top, c, t;
int ans[N], a[N];
int main() {
scanf("%d", &t);
while (t--) {
top = 0;
scanf("%d", &n);
a[0] = inf;
for (int i = 0; i < n; i++) {
scanf("%d", &c);
if (c < a[top]) {
a[++top] = c;
ans[i] = top;
} else {
int l = 1, h = top, m;
while (l <= h) {
m = (l + h) / 2;
if (c < a[m])
l = m + 1;
else
h = m - 1;
}
a[l] = c;
ans[i] = l;
}
}
printf("%d\n", top);
for (int i = 0; i < n; i++) {
if (i == n - 1)
printf("%d\n", ans[i]);
else
printf("%d ", ans[i]);
}
}
}