1. 程式人生 > 實用技巧 >CF930C Teodor is not a liar!(LIS)

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