//LIS 的变形
#include <iostream> #include <queue> #include <stack> #include <string> #include <map> #include <vector> #include <cstring> #include <cstdio> #include <cmath> #include <algorithm> using namespace std; const int MAX=200005,INF=1<<30; const int ROOT=0; int n; int a[MAX],c[MAX]; int dpL[MAX],dpR[MAX]; int ans,len; void setDp(){ dpR[n-1]=1; for(int i=n-2;i>=0;i--){ if(a[i]<a[i+1]) dpR[i]=dpR[i+1]+1; else dpR[i]=1; } dpL[0]=1; for(int i=1;i<n;i++){ if(a[i]>a[i-1]){ dpL[i]=dpL[i-1]+1; } else dpL[i]=1; } return ; } int bSearch(int x,int y,const int &val){ int mid; while(x<y){ mid=(x+y)>>1; if(c[mid]<val) x=mid+1; else y=mid; } return x-1; } int main() { #ifndef ONLINE_JUDGE freopen("i.txt", "r", stdin); #endif int T,pos; scanf("%d",&T); while(T--){ memset(c,0,sizeof(c)); scanf("%d",&n); for(int i=0;i<n;i++) scanf("%d",&a[i]); setDp(); ans=1; len=1; c[len]=a[0]; for(int i=1;i<n;i++){ pos=bSearch(1,len+1,a[i]); if(ans<pos+dpR[i]) ans=pos+dpR[i]; if(a[i]<c[dpL[i]] || dpL[i]>len){ c[dpL[i]]=a[i]; len=max(len,dpL[i]); } // if (a[j]<p[f1[j]] || gs<f1[j]){ // p[f1[j]]=a[j]; // if (gs<f1[j]) gs=f1[j]; // } } printf("%d\n",ans); } return 0; }
//最早用的线段树,,这种方法稍微不注意就TLE
#include <iostream> #include <queue> #include <stack> #include <string> #include <map> #include <vector> #include <cstring> #include <cstdio> #include <cmath> #include <algorithm> using namespace std; const int MAX=200005,INF=1<<30; const int ROOT=0; int n; int a[MAX],b[MAX]; int dpL[MAX],dpR[MAX]; int cnt; int f,result; int ans; struct NODE{ int b,e,val; NODE *lson,*rson; }; NODE node[MAX*2+5]; int bSearch(int x,int y,const int &val){ int mid; while(x<y){ mid=(x+y)>>1; if(b[mid]==val) return mid; else if(b[mid]<val) x=mid+1; else y=mid; } return -1; } void unique(){ f=0; result=0; sort(b,b+n); while(++f!=n){ if(b[result]!=b[f]){ b[++result]=b[f]; } } ++result; // cout<<"LEN: "<<result<<endl; for(int i=0;i<n;i++){ a[i]=bSearch(0,result,a[i])+1; // cout<<"A{i}: "<<a[i]<<endl; } return ; } void setDp(){ dpR[n-1]=1; for(int i=n-2;i>=0;i--){ if(a[i]<a[i+1]) dpR[i]=dpR[i+1]+1; else dpR[i]=1; } dpL[0]=1; for(int i=1;i<n;i++){ if(a[i]>a[i-1]){ dpL[i]=dpL[i-1]+1; // cout<<"ASD:"<<dpL[i]<<endl; } else dpL[i]=1; } // for(int i=0;i<n;i++) // cout<<dpL[i]<<" "<<dpR[i]<<endl; return ; } void built(NODE *root,int l,int r){ root->b=l; root->e=r; root->val=0; if(l>=r) return ; int mid=(l+r)>>1; root->lson=&node[++cnt]; built(root->lson,l,mid); root->rson=&node[++cnt]; built(root->rson,mid+1,r); return ; } void insert(NODE *root,int x,int val){ if(root->val<val) root->val=val; if(x==root->b&&root->e==x) return ; int mid=(root->b+root->e)>>1; if(x<=mid) insert(root->lson,x,val); else insert(root->rson,x,val); return ; } int search(NODE *root,const int &l,const int &r){ if(l<=root->b&&root->e<=r) return root->val; int mid=(root->b+root->e)>>1,maxVal=0; if(r<=mid) maxVal=max(maxVal, search(root->lson,l,r)); else if(l>=mid+1) maxVal=max(maxVal, search(root->rson,l,r)); else { maxVal=max(maxVal, search(root->lson,l,mid)); maxVal=max(maxVal, search(root->rson,mid+1,r)); } // if(l<=mid) // maxVal=max(maxVal, // search(root->lson,l,r)); // if(r>=mid+1) // maxVal=max(maxVal, // search(root->rson,l,r)); return maxVal; } void segmentTree(){ cnt=0; built(&node[ROOT],1,result); ans=dpR[0]; for(int i=1;i<n;i++){ insert(&node[ROOT],a[i-1],dpL[i-1]); if(1<=a[i]-1) ans=max(ans, search(&node[ROOT],1,a[i]-1)+dpR[i]); //cout<<"I: "<<i<<endl; } printf("%d\n",ans); return ; } int main() { #ifndef ONLINE_JUDGE freopen("i.txt", "r", stdin); // freopen("prefix.in","r",stdin); // freopen("prefix.out","w",stdout); #endif int T; scanf("%d",&T); while(T--){ scanf("%d",&n); for(int i=0;i<n;i++){ scanf("%d",&a[i]); b[i]=a[i]; } unique(); setDp(); segmentTree(); } return 0; }