比赛生涯的倒数第五发AC
#include <bits/stdc++.h>
using namespace std;
typedef pair<int, int> PII;
const int N = 1e6 + 10;
int n, t;
int a[N];
int color[N];
struct Node {
int l, r;
int sum, maxv, lazy;
void update(int x) {
sum += (r - l + 1) * x;
maxv += x;
lazy += x;
}
}tr[N << 2];
void pushup(int p) {
tr[p].sum = tr[p << 1].sum + tr[p << 1 | 1].sum;
tr[p].maxv = max(tr[p << 1].maxv, tr[p << 1 | 1].maxv);
}
void build(int p, int l, int r) {
tr[p].l = l, tr[p].r = r;
tr[p].sum = tr[p].lazy = 0;
if (l == r) {
tr[p].sum = a[l];
tr[p].maxv = 0;
return;
}
int mid = l + r >> 1;
build(p << 1, l, mid);
build(p << 1 | 1, mid + 1, r);
pushup(p);
}
void spread(int p) {
int lazy_val = tr[p].lazy;
if (lazy_val) {
tr[p << 1].update(lazy_val);
tr[p << 1 | 1].update(lazy_val);
tr[p].lazy = 0;
}
}
void update(int p, int l, int r, int val) {
if (l <= tr[p].l && tr[p].r <= r) {
tr[p].update(val);
} else {
spread(p);
int mid = tr[p].l + tr[p].r >> 1;
if(l <= mid) update(p << 1, l, r, val);
if (r > mid) update(p << 1 | 1, l, r, val);
pushup(p);
}
}
int query(int p, int l, int r) {
if (l <= tr[p].l && tr[p].r <= r)
return tr[p].maxv;
spread(p);
int ans = -(1 << 30);
int mid = tr[p].l + tr[p].r >> 1;
if (l <= mid) ans = max(ans, query(p << 1, l, r));
if (r > mid) ans = max(ans, query(p << 1 | 1, l, r));
return ans;
}
int main()
{
cin >> t;
while (t -- ) {
//memset(color, 0, sizeof color);
int res = 0;
scanf("%d", &n);
for (int i = 1; i <= n; i ++ ) scanf("%d", &a[i]);
build(1, 1, n + 1);
for (int i = 1; i <= n; i ++ ) {
int maxv = query(1, a[i] + 1, n + 1);
color[i] = maxv + 1;
// cout << "query" << i << " " << maxv << " " << endl;
update(1, a[i], a[i], color[i]);
res = max(res, color[i]);
}
printf("%d\n", res);
for (int i = 1; i <= n; i ++ )
printf("%d ", color[i]);
puts("");
}
return 0;
}