https://codeforces.ml/contest/1389/problem/F
法一:dp,所有区间按右端点排序,依次考虑“如果最后一个区间为该区间”的最优情况,它(叫做A)可以从一个“右端点比A的左端点小”的异类区间B转移过来,但是同时可以顺便把“B的右端点以右”的同类区间算上。算上同类区间可以用线段树维护:每次计算完一个区间[L,R]后,把右端点小于L的所有异类区间的dp值+1。
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define LL long long 4 5 int n; 6 const int maxn=400011; 7 8 struct SEG 9 { 10 int l,r,t; 11 bool operator < (const SEG &b) const 12 { 13 return r<b.r; 14 } 15 }seg[maxn]; 16 int lisa[maxn<<1],li=0; 17 18 int dp[maxn],contain[maxn]; 19 struct SmtNode{int Max,add;}; 20 struct SMT 21 { 22 SmtNode a[maxn<<2]; 23 int n; 24 SMT() {n=0;} 25 void clear(int N) {n=N;} 26 // int ls(int x) {return x<<1;} 27 // int rs(int x) {return (x<<1)|1;} 28 #define ls(x) (x<<1) 29 #define rs(x) ((x<<1)|1) 30 void up(int x) {a[x].Max=max(a[ls(x)].Max,a[rs(x)].Max);} 31 void addsingle(int x,int v) {a[x].Max+=v; a[x].add+=v;} 32 void down(int x) {if (a[x].add>0) {addsingle(ls(x),a[x].add); addsingle(rs(x),a[x].add); a[x].add=0;} } 33 void Insert(int x,int L,int R,int p,int v) 34 { 35 if (L==R) {a[x].Max=max(a[x].Max,v); return;} 36 down(x); 37 int mid=(L+R)>>1; 38 if (p<=mid) Insert(ls(x),L,mid,p,v); 39 else Insert(rs(x),mid+1,R,p,v); 40 up(x); 41 } 42 void insert(int p,int v) {Insert(1,0,n,p,v);} 43 int QPreMax(int x,int L,int R,int p) 44 { 45 if (R<=p) return a[x].Max; 46 down(x); 47 int mid=(L+R)>>1; 48 if (p<=mid) return QPreMax(ls(x),L,mid,p); 49 return max(QPreMax(ls(x),L,mid,p),QPreMax(rs(x),mid+1,R,p)); 50 } 51 int qPreMax(int p) {return QPreMax(1,0,n,p);} 52 void Add(int x,int L,int R,int ql,int qr,int v) 53 { 54 if (ql<=L && R<=qr) {addsingle(x,v); return;} 55 down(x); 56 int mid=(L+R)>>1; 57 if (ql<=mid) Add(ls(x),L,mid,ql,qr,v); 58 if (qr>mid) Add(rs(x),mid+1,R,ql,qr,v); 59 up(x); 60 } 61 void add(int L,int R,int v) {if (L<=R) Add(1,0,n,L,R,v);} 62 }s[2]; 63 64 int main() 65 { 66 scanf("%d",&n); 67 for (int i=1;i<=n;i++) 68 { 69 scanf("%d%d%d",&seg[i].l,&seg[i].r,&seg[i].t); 70 seg[i].t--; 71 lisa[++li]=seg[i].l; 72 lisa[++li]=seg[i].r; 73 } 74 sort(lisa+1,lisa+1+li); li=unique(lisa+1,lisa+1+li)-lisa-1; 75 for (int i=1;i<=n;i++) 76 { 77 seg[i].l=lower_bound(lisa+1,lisa+1+li,seg[i].l)-lisa; 78 seg[i].r=lower_bound(lisa+1,lisa+1+li,seg[i].r)-lisa; 79 } 80 sort(seg+1,seg+1+n); 81 // for (int i=1;i<=n;i++) cout<<"NO"<<i<<' '<<seg[i].l<<' '<<seg[i].r<<' '<<seg[i].t<<endl; 82 83 s[0].clear(li); s[1].clear(li); 84 dp[0]=0; 85 for (int i=1;i<=n;i++) 86 { 87 bool ty=seg[i].t; 88 dp[i]=s[ty^1].qPreMax(seg[i].l-1)+1; 89 s[ty].insert(seg[i].r,dp[i]); 90 s[ty^1].add(0,seg[i].l-1,1); 91 // cout<<i<<' '<<dp[i]<<endl; 92 } 93 94 int ans=0; 95 for (int i=1;i<=n;i++) ans=max(ans,dp[i]); 96 printf("%d\n",ans); 97 return 0; 98 }