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 ;
}
View Code

 

posted @ 2021-04-08 20:04  UpMing  阅读(207)  评论(0编辑  收藏  举报