参考 http://blog.youkuaiyun.com/L123012013048/article/details/45054857
一开始用set弄,erase弄超时了。
后半部分的方法十分不错。
一方面思路用二分搜索代替了暴力枚举。
另一方面,这种技巧有时能代替低效的set,大大提高效率,今后解题都可以参考。
前面的滑窗也有许多小细节需要处理。
#include<bits/stdc++.h>
using namespace std;
typedef pair<int,int> pii;
int MIN[200010];
int main()
{
int Z;
scanf("%d",&Z);
while(Z--)
{
vector<int>vec;
vector<int>f;
vector<int>g;
int temp;
int n;
scanf("%d",&n);
for(int i=0;i<n;i++)
{
scanf("%d",&temp);
vec.push_back(temp);
}
f.resize(vec.size());
g.resize(vec.size());
int l,r;
l=r=0;
while(1)
{
while(r<n)
{
g[r]=r-l+1;
if(l==r) r++;
else if(vec[r]>vec[r-1]) r++;
else break;
}
f[l]=r-l;
l++;
if(l==r&&r==n)
break;
}
/*for(int i=0;i<n;i++)
printf("%d ",f[i]);
puts("");
for(int i=0;i<n;i++)
printf("%d ",g[i]);
puts("");*/
int ans=1;
memset(MIN,0X3F,sizeof(MIN));
for(int i=0;i<n;i++)
{
int len=lower_bound(MIN+1,MIN+n+1,vec[i])-MIN;
ans=max(ans,len+f[i]-1);
MIN[g[i]]=min(MIN[g[i]],vec[i]);
}
printf("%d\n",ans);
}
return 0;
}
#include<bits/stdc++.h>
#define maxn 200010
using namespace std;
int l[maxn];
int r[maxn];
int A[maxn];
int n;
int MIN[maxn];
int main()
{
int Z;
scanf("%d",&Z);
while(Z--)
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%d",&A[i]);
int L,R;
L=R=1;
while(L<=n||R<=n)
{
while(R<=n&&A[R]>A[R-1])
{
l[R]=R-L+1;
R++;
}
while(L<R)
{
r[L]=R-L;
L++;
}
l[R]=1;
R++;
}
/*for(int i=1;i<=n;i++)
printf("%d ",l[i]);
puts("");
for(int i=1;i<=n;i++)
printf("%d ",r[i]);
puts("");*/
int ans=1;
memset(MIN,0X3F,sizeof(MIN));
for(int i=1;i<=n;i++)
{
int k=lower_bound(MIN+1,MIN+1+n,A[i])-MIN-1;
ans=max(ans,r[i]+k);
MIN[l[i]]=min(MIN[l[i]],A[i]);
}
printf("%d\n",ans);
}
return 0;
}