CF930C Teodor is not a liar!(LIS)

显然我们发现,如果出现两个峰,中间必然有点没被全部的区间覆盖,就得出了答案

因此我们只需要正反求一下最长上升子序列即可

 #include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<ll,ll> pll;
const int N=2e6+10;
const int inf=0x3f3f3f3f;
const int mod=1e9+7;
int a[N];
vector<int> num;
int f[N],g[N];
int main(){
    ios::sync_with_stdio(false);
    int n,m;
    cin>>n>>m;
    int i;
    for(i=1;i<=n;i++){
        int l,r;
        cin>>l>>r;
        a[l]++,a[r+1]--;
    }
    num.clear();
    for(i=1;i<=m;i++)
        a[i]+=a[i-1];
    num.push_back(a[1]);
    f[1]=1;
    for(i=2;i<=m;i++){
        if(a[i]>=num.back()){
            num.push_back(a[i]);
            f[i]=(int)num.size();
        }
        else{
            int pos=upper_bound(num.begin(),num.end(),a[i])-num.begin();
            num[pos]=a[i];
            f[i]=pos+1;
        }

    }
    num.clear();
    num.push_back(a[m]);
    for(i=m-1;i>=1;i--){
        if(a[i]>=num.back()){
            num.push_back(a[i]);
            g[i]=(int)num.size();
        }
        else{
            int pos=upper_bound(num.begin(),num.end(),a[i])-num.begin();
            num[pos]=a[i];
            g[i]=pos+1;
        }
    }
    ll ans=0;
    for(i=1;i<=m;i++){
        ans=max(1ll*f[i]+g[i]-1,ans);
    }
    cout<<ans<<endl;
    return 0;
}
View Code

 

posted @ 2020-08-28 11:26  朝暮不思  阅读(180)  评论(0编辑  收藏  举报