维护 $dp[i]$ 表示长度为 $i$ 的 $LIS$ 的最小结尾长度.
然后每次我们新加入一个区间 $[l,r]$ ,这个可以用平衡树来维护:区间平移,区间+1,单点赋值.
调不出来QAQ....
code:
#include <cstdio> #include <string> #include <cstring> #include <algorithm> #define ll long long #define N 300007 #define MAX 1200000000 #define lson s[x].ch[0] #define rson s[x].ch[1] #define setIO(s) freopen(s".in","r",stdin) using namespace std; struct node { int ch[2],f,v,tag,siz; node() { ch[0]=ch[1]=f=v=tag=siz=0;} }s[N]; int tot,root,ans; int newnode() { return ++tot; } inline void pushup(int x) { s[x].siz=s[lson].siz+s[rson].siz+1; } inline int get(int x) { return s[s[x].f].ch[1]==x; } inline void mark(int x,int v) { s[x].v+=v,s[x].tag+=v; } inline void pushdown(int x) { if(s[x].tag) { if(lson) mark(lson,s[x].tag); if(rson) mark(rson,s[x].tag); s[x].tag=0; } } inline void rotate(int x) { int old=s[x].f,fold=s[old].f,which=get(x); s[old].ch[which]=s[x].ch[which^1]; if(s[old].ch[which]) s[s[old].ch[which]].f=old; s[x].ch[which^1]=old,s[old].f=x,s[x].f=fold; if(fold) s[fold].ch[s[fold].ch[1]==old]=x; pushup(old),pushup(x); } inline void splay(int x,int &tar) { int u=s[tar].f; for(int fa;(fa=s[x].f)!=u;rotate(x)) if(s[fa].f!=u) rotate(get(fa)==get(x)?fa:x); tar=x; } void insert(int val) { int x=root,ff=0,d=0; while(x) { ff=x; pushdown(x); if(s[x].v<=val) x=rson,d=1; else x=lson,d=0; } int now=newnode(); s[now].v=val,s[now].siz=1,s[now].f=ff; if(ff) s[ff].ch[d]=now,pushup(ff); splay(now,root); } int find(int val) { // 第一个 小于 val 的 int x=root,an=0; while(x) { pushdown(x); if(s[x].v<val) an=x,x=rson; else x=lson; } return an; } int get_pre(int x) { splay(x,root),x=lson; while(rson) pushdown(x),x=rson; return x; } int get_nxt(int x) { splay(x,root),x=rson; while(lson) pushdown(x),x=lson; return x; } void Delete(int x) { splay(x,root); int L=s[x].ch[0],R=s[x].ch[1]; while(s[L].ch[1]) pushdown(L),L=s[L].ch[1]; splay(L,s[x].ch[0]); s[L].f=0; s[L].ch[1]=R,s[R].f=L,pushup(L),root=L; s[x].ch[0]=s[x].ch[1]=s[x].f=0; } void solve(int l,int r) { int u=find(l),v=find(r),nt=get_nxt(v); if(u!=v) { splay(u,root),splay(nt,s[u].ch[1]); int now=s[nt].ch[0]; if(now) mark(now,1); } if(nt!=2) Delete(nt),--ans; insert(l),++ans; } /* void Solve(int l,int r) { int u=Find(l),v=Find(r),nt=Getnxt(v); if(u^v) { Splay(u,0);Splay(nt,u); int QwQ=t[nt].ch[0]; t[QwQ].v+=1;t[QwQ].tag+=1; } if(nt!=2)Delete(nt),--ans; Insert(l),++ans; } */ int main() { // setIO("input"); int i,j,Q; insert(-MAX),insert(MAX); scanf("%d",&Q); for(i=1;i<=Q;++i) { int l,r; scanf("%d%d",&l,&r),solve(l,r); } printf("%d ",ans); return 0; }