# title

BZOJ 4553

LUOGU 4093

Description

``````1 2 3
2 2 3
1 3 3
1 1 3
1 2 4``````

``````3 3 3
3 2 3``````

Input

Output

Sample Input

3 4
1 2 3
1 2
2 3
2 1
3 4

Sample Output

3

# analysis

\[ f_i=f_j+1(j\leqslant i,Max_j\leqslant a_i,a_j\leqslant Min_i) \]

\(CDQ\) 分治可以这样做：

# code

\(CDQ\) 分治

``````#include<bits/stdc++.h>

const int maxn=3e5+10,MaxV=3e5;
typedef int iarr[maxn];

namespace IO
{
char buf[1<<15],*fs,*ft;
inline char getc() { return (ft==fs&&(ft=(fs=buf)+fread(buf,1,1<<15,stdin),ft==fs))?0:*fs++; }
{
x=0;
T f=1, ch=getchar();
while (!isdigit(ch) && ch^'-') ch=getchar();
if (ch=='-') f=-1, ch=getchar();
while (isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48), ch=getchar();
x*=f;
}

char Out[1<<24],*fe=Out;
inline void flush() { fwrite(Out,1,fe-Out,stdout); fe=Out; }
template<typename T>inline void write(T x,char str)
{
if (!x) *fe++=48;
if (x<0) *fe++='-', x=-x;
T num=0, ch[20];
while (x) ch[++num]=x%10+48, x/=10;
while (num) *fe++=ch[num--];
*fe++=str;
}
}

using IO::write;

template<typename T>inline bool chkMin(T &a,const T &b) { return a>b ? (a=b, true) : false; }
template<typename T>inline bool chkMax(T &a,const T &b) { return a<b ? (a=b, true) : false; }

namespace BIT
{
int c[maxn];
inline int lowbit(int x) { return x & -x; }
inline void add(int x,int k) { while (x<=MaxV) !k ? c[x]=0 : chkMax(c[x],k), x+=lowbit(x); }
inline int ask(int x) { int ans=0; while (x) chkMax(ans,c[x]), x-=lowbit(x); return ans; }
}

struct Orz{int x,y,id;}o[maxn];
inline bool cmp(const Orz &a,const Orz &b)
{
return a.x<b.x || (a.x==b.x && a.id<b.id);
}

iarr a,f,Max,Min;
inline void CDQ(int l,int r)
{
if (l==r) { chkMax(f[l],1); return ; }
int mid=(l+r)>>1;
CDQ(l,mid);
for (int i=l; i<=r; ++i)
{
if (i<=mid) o[i].x=a[i], o[i].y=Max[i];
else o[i].x=Min[i], o[i].y=a[i];
o[i].id=i;
}
std::sort(o+l,o+r+1,cmp);
for (int i=l; i<=r; ++i)
{
}
for (int i=l; i<=r; ++i) add(o[i].y,0);
CDQ(mid+1,r);
}

int main()
{
for (int i=1; i<=n; ++i) read(a[i]), Max[i]=Min[i]=a[i];
for (int i=1,x,v; i<=m; ++i)
{
chkMax(Max[x],v);
chkMin(Min[x],v);
}
CDQ(1,n);
int ans=0;
for (int i=1; i<=n; ++i) chkMax(ans,f[i]);
write(ans,'\n');
IO::flush();
return 0;
}``````

``````#include<bits/stdc++.h>

const int maxn=1e5+10,MaxV=1e5;
typedef int iarr[maxn];

namespace IO
{
char buf[1<<15],*fs,*ft;
inline char getc() { return (ft==fs&&(ft=(fs=buf)+fread(buf,1,1<<15,stdin),ft==fs))?0:*fs++; }
{
x=0;
T f=1, ch=getchar();
while (!isdigit(ch) && ch^'-') ch=getchar();
if (ch=='-') f=-1, ch=getchar();
while (isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48), ch=getchar();
x*=f;
}

char Out[1<<24],*fe=Out;
inline void flush() { fwrite(Out,1,fe-Out,stdout); fe=Out; }
template<typename T>inline void write(T x,char str)
{
if (!x) *fe++=48;
if (x<0) *fe++='-', x=-x;
T num=0, ch[20];
while (x) ch[++num]=x%10+48, x/=10;
while (num) *fe++=ch[num--];
*fe++=str;
}
}

using IO::write;

template<typename T>inline bool chkMin(T &a,const T &b) { return a>b ? (a=b, true) : false; }
template<typename T>inline bool chkMax(T &a,const T &b) { return a<b ? (a=b, true) : false; }
template<typename T>inline T min(T a,T b) { return a<b ? a : b; }
template<typename T>inline T max(T a,T b) { return a>b ? a : b; }

struct SGT
{
struct Orz{int l,r,z;}c[maxn*100]; int cnt;
inline void Change(int &x,int l,int r,int pos,int k)
{
if (!x) x=++cnt;
chkMax(c[x].z,k);
if (l==r) return ;
int mid=(l+r)>>1;
if (pos<=mid) Change(c[x].l,l,mid,pos,k);
else Change(c[x].r,mid+1,r,pos,k);
}

inline int query(int x,int l,int r,int tl,int tr)
{
if (!x || l>tr || r<tl) return 0;
if (tl<=l && r<=tr) return c[x].z;
int mid=(l+r)>>1;
return max(query(c[x].l,l,mid,tl,tr),query(c[x].r,mid+1,r,tl,tr));
}
} sgt;

iarr a,Max,Min,f;
struct BIT
{
int rt[maxn];
inline int lowbit(int x) { return x & -x; }

{
for (int i=a[x]; i<=MaxV; i+=lowbit(i)) sgt.Change(rt[i],1,MaxV,Max[x],f[x]);
}

{
int ans=0;
for (int i=Min[x]; i>=1; i-=lowbit(i)) chkMax(ans,sgt.query(rt[i],1,MaxV,1,a[x]));
return ans;
}
}bit;

int main()
{
for (int i=1; i<=n; ++i) read(a[i]), Max[i]=Min[i]=a[i];
for (int i=1,x,v; i<=m; ++i)
{
chkMax(Max[x],v);
chkMin(Min[x],v);
}
int ans=0;
for (int i=1; i<=n; ++i)
{
chkMax(ans,f[i]);