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; }
没有人不辛苦,只有人不喊疼