思路:
动态规划。
类似于线段覆盖,首先对每个区间的右端点从小到大排好序。对于每个区间$s_i$,状态转移方程为$f_{s_i.r}=\max\limits_{0\leq j\leq s_i.l}\{f_j\}$。对于这个$max$,我们可以用一个树状数组来维护前缀最大值。有$n$组区间,区间范围是$0\sim m$,渐近时间复杂度为$O(n\log m)$。另外注意区间有可能为$0$,用树状数组不好维护,因此我们可以将所有的端点$+1$。1 #include2 #include 3 #include 4 #include 5 inline int getint() { 6 char ch; 7 while(!isdigit(ch=getchar())); 8 int x=ch^'0'; 9 while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0');10 return x;11 }12 const int N=150000,M=3000002;13 int m=0;14 class FenwickTree {15 private:16 int val[M];17 int lowbit(const int x) {18 return x&-x;19 }20 public:21 FenwickTree() {22 memset(val,0,sizeof val);23 }24 void modify(int p,const int x) {25 while(p<=m) {26 val[p]=std::max(val[p],x);27 p+=lowbit(p);28 }29 }30 int query(int p) {31 int ret=0;32 while(p) {33 ret=std::max(ret,val[p]);34 p-=lowbit(p);35 }36 return ret;37 }38 };39 FenwickTree t;40 int f[M]={ 0};41 struct Segment {42 int x,y;43 bool operator < (const Segment &another) const {44 return y f[y]) {61 t.modify(y,f[y]=tmp);62 ans=std::max(ans,tmp);63 }64 }65 printf("%d\n",ans);66 return 0;67 }