UVa1471 LIS变种 nlgn
//#include<bits/stdc++.h> #include<stdio.h> #include<algorithm> #include<queue> #include<string.h> #include<iostream> #include<math.h> #include<set> #include<map> #include<vector> #include<iomanip> using namespace std; #define ll long long #define pb push_back const int maxn=2e5+9; int f[maxn];//以i开头的长度 int g[maxn];//以i结尾的长度 int d[maxn]; const int inf=0x3f3f3f3f; int arr[maxn]; int main(){ int T; scanf("%d",&T); while(T--){ int n; scanf("%d",&n); for(int i=1;i<=n;i++)scanf("%d",&arr[i]); f[1]=1; for(int i=2;i<=n;i++){ if(arr[i]>arr[i-1])f[i]=f[i-1]+1; else f[i]=1; } g[n]=1; for(int i=n-1;i>=1;i--){ if(arr[i]<arr[i+1])g[i]=g[i+1]+1; else g[i]=1; } int ans=0; for(int i=1;i<=n;i++)d[i]=inf;//长度i的头所需代价 for(int i=1;i<=n;i++){ int len=(lower_bound(d+1,d+1+i,arr[i])-(d+1))+g[i]; ans=max(ans,len); d[f[i]]=min(arr[i],d[f[i]]); } printf("%d\n",ans); } }
d数组性质就是同样的长度存最小的开始点,维护数组前部的一个理想前半
长度增长1数值至少加1,d数组单调增,
所以可以边修改边用lowerbound