To get a small strong array of 3 × n, to choose a number in each column (or not selected), the following conditions are satisfied:
1. If the first row is selected, then it must be a number greater than or equal
2. If the second row is selected, it must be less than equal to a number
3. If the third row is selected, for a continuous period of several selected in the third row, must satisfy the same direction (less than or equal to a number equal to a number greater than)
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<bits/stdc++.h> using namespace std; #define rep(i,a,b) for(int i=(a);i<=(b);i++) #define repp(i,a,b) for(int i=(a);i>=(b);--i) #define ll long long #define see(x) (cerr<<(#x)<<'='<<(x)<<endl) #define inf 0x3f3f3f3f #define CLR(A,v) memset(A,v,sizeof A) ///////////////////////////////////// const int N=3e5+100; int maxx[5][N<<2],nn,n,b[N<<2],dp[N][5],ans,a[N][4]; void upnode(int id,int x,int v,int l,int r,int pos) { if(l==r){maxx[id][pos]=max(maxx[id][pos],v);return ;} int m=(l+r)>>1; if(x<=m)upnode(id,x,v,l,m,pos<<1); else upnode(id,x,v,m+1,r,pos<<1|1); maxx[id][pos]=max(maxx[id][pos<<1],maxx[id][pos<<1|1]); } int qmaxx(int id,int L,int R,int l,int r,int pos) { if(L<=l&&r<=R)return maxx[id][pos]; int m=(l+r)>>1;int ans=0; if(L<=m)ans=max(ans,qmaxx(id,L,R,l,m,pos<<1)); if(R>m)ans=max(ans,qmaxx(id,L,R,m+1,r,pos<<1|1)); return ans; } int main() { scanf("%d",&n); rep(i,1,n)scanf("%d",&a[i][1]),b[++nn]=a[i][1]; rep(i,1,n)scanf("%d",&a[i][2]),b[++nn]=a[i][2]; rep(i,1,n)scanf("%d",&a[i][3]),b[++nn]=a[i][3]; sort(b+1,b+1+nn); nn=unique(b+1,b+1+nn)-b-1; rep(i,1,n)a[i][1]=lower_bound(b+1,b+1+nn,a[i][1])-b, a[i][2]=lower_bound(b+1,b+1+nn,a[i][2])-b, a[i][3]=lower_bound(b+1,b+1+nn,a[i][3])-b; rep(i,1,n) { dp[i][1]=max(dp[i][1],qmaxx(1,1,a[i][1],1,nn,1)); dp[i][1]=max(dp[i][1],qmaxx(2,1,a[i][1],1,nn,1)); dp[i][1]=max(dp[i][1],qmaxx(3,1,a[i][1],1,nn,1)); dp[i][1]=max(dp[i][1],qmaxx(4,1,a[i][1],1,nn,1)); dp[i][1]++; dp[i][2]=max(dp[i][2],qmaxx(1,a[i][2],nn,1,nn,1)); dp[i][2]=max(dp[i][2],qmaxx(2,a[i][2],nn,1,nn,1)); dp[i][2]=max(dp[i][2],qmaxx(3,a[i][2],nn,1,nn,1)); dp[i][2]=max(dp[i][2],qmaxx(4,a[i][2],nn,1,nn,1)); dp[i][2]++; dp[i][3]=max(dp[i][3],qmaxx(1,1,a[i][3],1,nn,1)); dp[i][3]=max(dp[i][3],qmaxx(2,1,a[i][3],1,nn,1)); dp[i][3]=max(dp[i][3],qmaxx(3,1,a[i][3],1,nn,1)); dp[i][3]++; dp[i][4]=max(dp[i][4],qmaxx(1,a[i][3],nn,1,nn,1)); dp[i][4]=max(dp[i][4],qmaxx(2,a[i][3],nn,1,nn,1)); dp[i][4]=max(dp[i][4],qmaxx(4,a[i][3],nn,1,nn,1)); dp[i][4]++; upnode(1,a[i][1],dp[i][1],1,nn,1); upnode(2,a[i][2],dp[i][2],1,nn,1); upnode(3,a[i][3],dp[i][3],1,nn,1); upnode(4,a[i][3],dp[i][4],1,nn,1); } rep(i,1, n) rep (j, 1 , 4 ) years = max (years dp [i] [j]); cout << years; return 0 ; }