Title Link: Bzoj Valley
\ (O (n^2) \) DP is very good to write, for the current I from before satisfy the condition of J Select a maximum value,\ (dp[i]=d[j]+1\)
for(int j=1; j<i; ++j) if(a[j]<=minv[i]&&maxv[j]<=a[i])//序列只会变换一次 dp[i]=max{dp[j]+1};
Transfer to meet two conditions:\ (a[j]<=minv[i]\ \&\&\ maxv[j]<=a[i]\)
A two-dimensional partial order problem, CDQ, tree set tree can be.
Take \ (minv[x]\) and \ (a[y]\) as two axes,\ (dp[j]\) represents its previous point \ ((a[j],maxv[j]) \).
This becomes a two-dimensional plane, where you can insert some point dp[i], asking for a point maximum in a rectangular area (also a prefix)
Segment tree Set segment tree tree array set of line segments tree can do complexity \ (O (nlog^2n) \)
The latter time can also
Tree array nested segment tree:
//Attempt a two-dimensional tree array but with a dynamic opening, an interval without a middle section breaks the query in the y direction.#include <cstdio>#include <cctype>#include <algorithm>#define GC () GetChar ()#define NOW NODE[RT]#define Lson L,m,node[rt].ls#define Rson m+1,r,node[rt].rs#define LB (x) ((x) &-(x))Const intn=1e5+5;intN,m,a[n],minv[n],maxv[n],maxv,maxa;namespacetree_2d{structSeg_tree {structNode {intMaxv,ls,rs; }node[n<<6];//And a little bit more. Otherwise the bzoj still on the Mle inline intNew_node () {Static intCnt=0;return++cnt; }voidInsert (intLintRint&rt,intPintV) {if(!rt) RT = New_node (); NOW.MAXV = Std::max (NOW.MAXV, v);if(L<r) {intM=l+r>>1;if(p<=m) Insert (LSON,P,V);ElseInsert (RSON,P,V); } }intQuery (intLintRintRtintLintR) {if(!RT)return 0;if(L<=l && r<=r)returnNOW.MAXV;intM=l+r>>1;if(l<=m)if(M<r)returnStd::max (Query (lson,l,r), query (Rson,l,r));Else returnQuery (LSON,L,R);returnQuery (RSON,L,R); }}t;structBit {intRoot[n];voidInsert (intPintYintV) { while(P<=MAXV) T.insert (1, maxa,root[p],y,v), p+=lb (p); }intQuery (intPintY) {intres=0; while(p) Res=std::max (Res,t.query (1, Maxa,root[p],1, y)), p-=lb (p);returnRes }}t2d;}#undef Nowinline intRead () {intnow=0;Register CharC=GC (); for(;! IsDigit (c); C=GC ()); for(; IsDigit (c); now=now*Ten+c-' 0 ', C=GC ());returnNow;}intMain () {N=read (), M=read (); for(intI=1; i<=n; ++i) Maxv[i]=minv[i]=a[i]=read (), Maxa=std::max (Maxa,a[i]); for(intX,y,i=1; i<=m; ++i) X=read (), Y=read (), Maxv[x]=std::max (Maxv[x],y), Minv[x]=std::min (minv[x],y); for(intI=1; i<=n; ++i) Maxv=std::max (Maxv,maxv[i]);intans=0; for(intV,i=1; i<=n; ++i) {v = tree_2d::t2d.query (Minv[i],a[i]) +1; Tree_2d::t2d.insert (A[I],MAXV[I],V); Ans=std::max (ANS,V); } printf ("%d", ans);return 0;}
Two-dimensional segment tree:
/*Bzoj on the direct mle ... Rokua P4093 4508ms (3 times times slower than bit set Segtree +) 293.33MBspace consumption compare capital pointers bar. */#include <cstdio>#include <cctype>#include <algorithm>#define GC () GetChar ()#define Lson L,m,rt->ls#define Rson M+1,r,rt->rsConst intn=1e5+5;intN,M,A[N],MAXV[N],MINV[N],MAXA,MAXV;namespaceseg_tree2d{structNode {intMAXV; Node *ls,*rs; Node (): MAXV (0), LS (null), RS (null) {}}pool[n<<7];//(LOGN) ^2=256 (2^8) Turn it down, or the space will explode. structnode2d {Node *root; Node2d *ls,*rs; Node2d (): Root (null), LS (null), RS (null) {}}pool2d[n<<1],*root;inlineNode *new_node () {Static intCnt=0;return&pool[cnt++]; }inlineNode2d *new_node2d () {Static intCnt=0;return&pool2D[cnt++]; } node2d *build (intLintR) {node2d *rt = new_node2d ();if(L<r) {intM=l+r>>1; Rt->ls = Build (l,m); Rt->rs = Build (M+1, R); }returnRt }intQuery (intLintR,node *rt,intLintR) {if(!RT)return 0;if(L<=l && r<=r)returnrt->maxv;intM=l+r>>1;if(l<=m)if(M<r)returnStd::max (Query (lson,l,r), query (Rson,l,r));Else returnQuery (LSON,L,R);returnQuery (RSON,L,R); }intQuery2d (intLintR,node2d *rt,intLintRintY1,inty2) {if(L<=l && r<=r)returnQuery (1, maxa,rt->root,y1,y2);intM=l+r>>1;if(l<=m)if(M<r)returnStd::max (Query2d (Lson,l,r,y1,y2), query2d (Rson,l,r,y1,y2));Else returnQuery2d (LSON,L,R,Y1,Y2);returnQuery2d (RSON,L,R,Y1,Y2); }voidInsert (intLintR,node *&rt,intPintV) {if(!rt) RT = New_node ();//!RT->MAXV = Std::max (RT->MAXV, v);if(L<r) {intM=l+r>>1;if(p<=m) Insert (LSON,P,V);ElseInsert (RSON,P,V); } }voidINSERT2D (intLintR,node2d *rt,intPintYintV) {Insert (1, MaxA, Rt->root, y, v);if(L<r) {intM=l+r>>1;if(p<=m) INSERT2D (LSON,P,Y,V);ElseINSERT2D (RSON,P,Y,V); } }voidInit () {root = Build (1, MAXV); }intQuery_max (intLintRintY1,inty2) {returnQuery2d (1, maxv,root,l,r,y1,y2); }voidInsert_node (intXintYintV) {insert2d (1, maxv,root,x,y,v); }}inline intRead () {intnow=0;Register CharC=GC (); for(;! IsDigit (c); C=GC ()); for(; IsDigit (c); now=now*Ten+c-' 0 ', C=GC ());returnNow;}intMain () {N=read (), M=read (); for(intI=1; i<=n; ++i) Maxv[i]=minv[i]=a[i]=read (), Maxa=std::max (Maxa,a[i]); for(intX,y,i=1; i<=m; ++i) X=read (), Y=read (), Maxv[x]=std::max (Maxv[x],y), Minv[x]=std::min (minv[x],y); for(intI=1; i<=n; ++i) Maxv=std::max (Maxv,maxv[i]); Seg_tree2d::init ();intans=0; for(intV,i=1; i<=n; ++i) {v = Seg_tree2d::query_max (1, Minv[i],1, A[i]) +1; Seg_tree2d::insert_node (A[I],MAXV[I],V); Ans=std::max (ANS,V); } printf ("%d", ans);return 0;}
bzoj.4553. [heoi2016&tjoi2016] Sequence (DP tree array set segment tree/two-D segment tree (MLE) dynamic open point) 4