2020ICPC昆明 L.Simone and graph coloring(思维+nlog(n)的最长下降子序列)
Posted issue是fw
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2020ICPC昆明 L.Simone and graph coloring(思维+nlog(n)的最长下降子序列)相关的知识,希望对你有一定的参考价值。
给定长度 n n n的数组 a a a
若 i < j & & a i > a j i<j\\&\\&a_i>a_j i<j&&ai>aj,那么 i , j i,j i,j之间有一条无向边
使用最少的颜色给这个图染色,使得每条边连接的两个顶点颜色都是不同的
这种形如逆序对的连边方式,最后的图应该是一个 D A G DAG DAG
i i i会和 j ∈ [ 1 , i − 1 ] & & a j > a i j\\in[1,i-1]\\&\\&a_j>a_i j∈[1,i−1]&&aj>ai的所有 j j j连边
那么设所有 j j j的颜色是 1 1 1, i i i的颜色是 2 2 2
此时后面有一个 k k k与 i i i连边,那么也会和前面所有 j j j连边
所以 k k k的颜色是 3 3 3…
如此这般,我们发现求一个 D A G DAG DAG上的最长路就好了
而且这个 D A G DAG DAG非常特殊,所以只需要求一个最长上升子序列即可
并且发现,如果令 f [ i ] f[i] f[i]表示以 i i i结尾的最长上升子序列,那么 f i f_i fi也是他的颜色
这样不会引起冲突
但是突然脑瘫不会写 n l o g ( n ) nlog(n) nlog(n)的最长下降子序列
灵机一动把每个数变成 1 0 9 − a i 10^9-a_i 109−ai,于是求一个最长上升子序列就好了
#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e6+10;
int t,n,f[maxn],d[maxn],a[maxn];
int main()
{
cin >> t;
while( t-- )
{
cin >> n;
for(int i=1;i<=n;i++) scanf("%d",&a[i] ),a[i] = 1e9-a[i];
int ans = 0;
f[1] = 1, d[++ans] = a[1];
for(int i=2;i<=n;i++)
{
int id = lower_bound( d+1,d+1+ans,a[i] )-d;
if( id<=ans ) d[id] = a[i];
else d[++ans] = a[i];
f[i] = id;
}
printf("%d\\n",ans);
for(int i=1;i<=n;i++) printf("%d ",f[i] );
puts("");
}
}
以上是关于2020ICPC昆明 L.Simone and graph coloring(思维+nlog(n)的最长下降子序列)的主要内容,如果未能解决你的问题,请参考以下文章