题解:
$dp$。
有$$f[r[i]]=min(f[k]+1)$$。
然后用线段树优化转移就好了。
代码:
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; #define N 25050 #define T 1000050 inline int rd() { int f=1,c=0;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){c=10*c+ch-'0';ch=getchar();} return f*c; } int n,t; struct Pair { int l,r; }p[N]; bool cmp(Pair x,Pair y) { if(x.r!=y.r)return x.r<y.r; return x.l<y.l; } int dp[T]; struct segtree { int vl[T<<2]; void update(int u) { vl[u] = min(vl[u<<1],vl[u<<1|1]); } void build(int l,int r,int u) { if(l==r) { vl[u] = dp[l]; return ; } int mid = (l+r)>>1; build(l,mid,u<<1); build(mid+1,r,u<<1|1); update(u); } void insert(int l,int r,int u,int qx,int d) { if(l==r) { vl[u]=d; return ; } int mid = (l+r)>>1; if(qx<=mid)insert(l,mid,u<<1,qx,d); else insert(mid+1,r,u<<1|1,qx,d); update(u); } int query(int l,int r,int u,int ql,int qr) { if(l==ql&&r==qr)return vl[u]; int mid = (l+r)>>1; if(qr<=mid)return query(l,mid,u<<1,ql,qr); else if(ql>mid)return query(mid+1,r,u<<1|1,ql,qr); else return min(query(l,mid,u<<1,ql,mid),query(mid+1,r,u<<1|1,mid+1,qr)); } }tr; int main() { n = rd(),t = rd(); for(int i=1;i<=n;i++) p[i].l = rd(),p[i].r = rd(); sort(p+1,p+1+n,cmp); memset(dp,0x3f,sizeof(dp)); dp[0]=0; tr.build(0,t,1); for(int i=1;i<=n;i++) { int tmp = tr.query(0,t,1,p[i].l-1,p[i].r)+1; if(dp[p[i].r]>tmp) { dp[p[i].r] = tmp; tr.insert(0,t,1,p[i].r,tmp); } } printf("%d ",dp[t]==0x3f3f3f3f?-1:dp[t]); return 0; }