UVALive 4976 Defense Lines


//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
",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
",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; }