2021icpc昆明区域赛-L-Simone and Graph Coloring(权值线段树)
题目大意:
给你一个排列,所有的逆序对的颜色不能相同,问最少用几种颜色并输出方案数字
题目思路:
因为逆序对是具有传递关系的
排列 3 2 1
如果3用颜色1
那么2就得用颜色2
因为1和3也有逆序关系,所以,1不能用2和1,所以1用3
-------------------------------------
容易发现
对于a[i]我们只需要找到在[a[i],max_num]中的color的最大值然后加一就可以了
我么可以用权值线段树维护这个color,以叶子节点为数字a[i],然后把color传上去,维护区间的最大值
int n, val[maxn], ans[maxn]; struct node { int ma; } a[maxn * 4]; void push(int st) { a[st].ma = max(a[st * 2].ma, a[st * 2 + 1].ma); } void build(int st, int l, int r) { a[st].ma = 0 ; if(l == r) { return ; } int mid = (l + r) >> 1; build(st * 2, l, mid); build(st * 2 + 1, mid + 1, r); push(st); } void update(int st, int l, int r, int pos, int num) { if(l == r) { a[st].ma = num; return ; } int mid = (l + r) >> 1; if(pos <= mid) update(st * 2, l, mid, pos, num); else update(st * 2 + 1, mid + 1, r, pos, num); push(st); } int qmax(int st, int l, int r, int ql, int qr) { if(ql <= l && qr >= r) return a[st].ma; int ma = 0; int mid = (l + r) >> 1; if(ql <= mid) ma = max(ma, qmax(st * 2, l, mid, ql, qr)); if(qr > mid) ma = max(ma, qmax(st * 2 + 1, mid + 1, r, ql, qr)); return ma; } int main() { int _ = read(); while(_--) { n = read(); rep(i, 1, n) val[i] = read(); build(1, 1, n); for(int i = 1 ; i <= n ; i++) { ans[i] = qmax(1, 1, n, val[i] + 1, n) + 1; update(1, 1, n, val[i], ans[i]); } out(qmax(1, 1, n, 1, n)); puts(""); rep(i, 1, n) printf("%d ", ans[i] ); puts(""); } return 0 ; }