你发现只会改变一个位置,所以可以直接进行dp
具体转移的话用 CDQ 分治转移就好了~
#include <bits/stdc++.h>
#define N 100006
#define setIO(s) freopen(s".in","r",stdin)
using namespace std;
int n,m;
int C[N],f[N];
int lowbit(int t)
{
return t&(-t);
}
void CL(int x)
{
while(x<N) C[x]=0, x+=lowbit(x);
}
void add(int x,int v)
{
while(x<N) C[x]=max(C[x],v), x+=lowbit(x);
}
int query(int x)
{
int re=0;
while(x) re=max(re,C[x]), x-=lowbit(x);
return re;
}
struct node
{
int val,id,mn,mx;
}a[N];
bool cmp1(node a,node b)
{
return a.id<b.id;
}
bool cmp2(node a,node b)
{
return a.val<b.val;
}
int cmp3(node a,node b)
{
return a.mn<b.mn;
}
void solve(int l,int r)
{
if(l>=r) return;
int mid=(l+r)>>1;
solve(l,mid);
sort(a+l,a+1+mid,cmp2); sort(a+mid+1,a+1+r,cmp3);
for(int i=mid+1,j=l;i<=r;++i)
{
while(a[j].val<=a[i].mn&&j<=mid) add(a[j].mx,f[a[j].id]),++j;
f[a[i].id]=max(f[a[i].id], query(a[i].val)+1);
}
for(int i=l;i<=mid;++i) CL(a[i].mx);
sort(a+mid+1,a+r+1,cmp1), solve(mid+1,r);
}
int main()
{
//setIO("input");
int i,j,re=0;
scanf("%d%d",&n,&m);
for(i=1;i<=n;++i) f[i]=1, scanf("%d",&a[i].val),a[i].id=i,a[i].mn=a[i].mx=a[i].val;
for(i=1;i<=m;++i)
{
int x,y;
scanf("%d%d",&x,&y);
a[x].mn=min(a[x].mn, y);
a[x].mx=max(a[x].mx, y);
}
solve(1,n);
for(i=1;i<=n;++i) re=max(re,f[i]);
printf("%d\n",re);
return 0;
}