Simone and Graph Coloring (nowcoder.com)
题意:
n个数的序列,逆序对之间有一条边,这样就成了n个节点的图,现在对图进行染色,要求同一条边上的两点异色,求最小颜色数,并将每一点染色情况输出。
分析:
因为逆序对成边,所以下降子序列单独来看,就是一个完全图,对完全图染色,颜色数等于节点数。所以最小颜色数即为最长下降子序列长度。
Code:
#include <bits/stdc++.h>
using namespace std;
const int N = 1e6+7;
int a[N],d[N],len,n,ans[N],t;
int binary(int x, int l, int r)
{
while(l<=r)
{
int mid = (l + r)/2;
if(d[mid] <= x) r = mid-1;
else l = mid+1;
}
return l;
}
int main()
{
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
for(int i = 1; i <= n; i++) scanf("%d",&a[i]);
ans[1]=1; len = 1; d[len]=a[1];
for(int i=2;i<=n;i++)
{
if(a[i]<d[len])
d[++len]=a[i], ans[i]=len;
else
{
int p=binary(a[i],1,len);
d[p]=a[i];
ans[i]=p;
}
}
printf("%d\n",len);
for(int i=1;i<=n;i++) printf("%d ",ans[i]);
printf("\n");
}
return 0;
}