你发现只会改变一个位置,所以可以直接进行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 ",re); return 0; }