2020 ICPC KUNMING L (求最长下降子序列 线段树 or DP)

文章介绍了如何解决L.Simone and Graph Coloring问题,该问题涉及求解序列的最长下降子序列。通过建立线段树或者采用动态规划(DP)的方法,可以找到每个点的最长下降子序列,进而确定最小所需颜色数量。线段树方法用于区间维护最长下降子序列的长度,而DP方法则通过对序列进行O(nlogn)遍历来求解。注意,使用cin, cout可能导致超时,建议优化输入输出方式。" 82802368,7770087,深入理解Linux:文件权限管理-chgrp、chown与chmod,"['Linux指令', '文件权限管理']
摘要由CSDN通过智能技术生成

L.Simone and Graph Coloring (求最长下降子序列)

题目

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
       给你一个从1到n的序列,如果存在逆序对<a[i], a[j]>,那么a[i], a[j]之间有一条边。这样,这些点能组成一张图。现在给这些点染色,要求相连的两个点之间的颜色不能相同。问你最小需要多少种颜色把图全部染完,且输出每个点需要染的颜色,染色编号从1到n。
       只要有逆序对,就有边,就不能颜色相同。可以发现,对于a[i],它与前面比它大的点的颜色都不相同,且染色的编号是包含该点的最长下降子序列+1.
       所以转求每个点的最长下降子序列。
有两种方法:
1、线段树求最长下降子序列
2、类比求最长上升子序列LIS,用DP+单调栈求最长下降子序列

线段树求最长下降子序列

线段树区间维护包含每个数的最长下降子序列数。
       1、建树:区间初始化为0
       2、更新:点goal的值为x
       3、查询:查询区间[l, r]的最大值。即这个区间里的数的最大最长下降子序列数。
       
思路:
       对于输入的每一个数a[i],都查询比它大的区间里的最大值MAX,这样保证找到的是最长下降子序列。那么对于数a[i],它的最长下降子序列数为MAX+1,把这个点更新掉即可。
       

#include<bits/stdc++.h>
using namespace std;
#define ll long long
const ll maxn = 1e6+5;
ll t, n,ans[maxn];
ll a[maxn], res;
ll cnt[maxn<<2];

void Build(ll l, ll r, ll pos){
   
    if(l == r){
   cnt[pos] = 0; return; }
    ll m = (l+r)>>1;
    Build(l, m, pos<<1);
    Build(m+1, r, pos<<1|1);
    cnt[pos] = cnt[pos<<1] + cnt[pos<<
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值