题意:
给一个长度为n(n <= 200000) 的序列,你删除一段连续的子序列,使得剩下的序列拼接起来,有一个最长的连续递增子序列
分析:
就是最长上升子序列的变形。需要加一个类似二分搜索就好。
代码:
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
const int maxn=200005;
const int INF=1000000000;
int a[maxn],g[maxn],d[maxn];
int r[maxn];
int l[maxn];
int main()
{
int t,n,ans;
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
int i,j;
for(i=0;i<n;i++)
scanf("%d",&a[i]);
memset(l,0,sizeof(l));
memset(r,0,sizeof(r));
r[n-1] = 1;l[0] = 1;
for(i=n-2;i>=0;i--)
{
if(a[i]>=a[i+1])
r[i]=1;
else
r[i]=r[i+1]+1;
}
for(i=1;i<=n-1;i++)
{
if(a[i]>a[i-1])
l[i]=l[i-1]+1;
else
l[i]=1;
}
ans=-1;
for(i=1;i<=n;i++)
g[i]=INF;
for(i=0;i<n;i++)
{
int k=lower_bound(g+1,g+n+1,a[i])-g;
d[i]=k+r[i]-1;
if(a[i]<g[l[i]])
g[l[i]]=a[i];
ans=max(ans,d[i]);
}
printf("%d ",ans);
}
}