Codeforces 931F - Teodor is not a liar!

931F - Teodor is not a liar!

思路:

最长上升子序列

先差分数组染色

如果存在一个点,被所有区间包含,那么这张图一定是山峰状,如下图:

那么只要分别从前和从后找一个最长非严格上升子序列,然后从前往后更新就可以找出最大的山峰序列的长度,这个就是答案

代码:

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define pb push_back
#define mem(a,b) memset(a,b,sizeof(a))

const int N=1e5+5;
const int INF=0x3f3f3f3f;
int a[N],dp[N],pre[N],suf[N];
int main(){
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int n,m,l,r;
    cin>>n>>m;
    for(int i=1;i<=n;i++)cin>>l>>r,a[l]++,a[r+1]--;
    for(int i=2;i<=m;i++)a[i]+=a[i-1];
    mem(dp,INF);
    for(int i=1;i<=m;i++){
        *upper_bound(dp+1,dp+m+1,a[i])=a[i];
        pre[i]=lower_bound(dp+1,dp+m+1,INF)-dp-1;
    }
    mem(dp,INF);
    for(int i=m;i>=1;i--){
        *upper_bound(dp+1,dp+m+1,a[i])=a[i];
        suf[i]=lower_bound(dp+1,dp+m+1,INF)-dp-1;
    }
    int ans=0;
    for(int i=0;i<=m;i++)ans=max(ans,pre[i]+suf[i+1]);
    cout<<ans<<endl;
    return 0;
}

 

posted @ 2018-03-06 16:40  Wisdom+.+  阅读(618)  评论(0编辑  收藏  举报