点击打开链接
//这道 题似乎是默认一定会成功的,而且是按大小顺序输入的? //#include "stdafx.h" #include <cstdio> #include <cstdlib> #define MAXN 100001 #define MAX 500001 struct node { long x, y, w; } T[MAXN *2]; long N, M, S, Val; void build(long p, long a, long b)//建树 { T[p].x = a; T[p].y = b; T[p].w = MAX; if (a + 1 < b) { build(p*2, a, a + b >> 1); build(p*2+1, a + b >> 1, b); } } void update(long p)//将 0 到 S的 中比val大的线段 标志更新为 val { if (T[p].w > Val) T[p].w = Val; if (T[p].x + 1 < T[p].y) if (S <= T[p].x + T[p].y >> 1) update(p*2); else update(p*2+1); } long query(long p, long a, long b)//找到 s 之前较小的标志 { if ((a <= T[p].x) && (T[p].y <= b))//如果 包含 则返回 return T[p].w; long mid = T[p].x + T[p].y >> 1; if (b <= mid)// 左子树 return query(p*2, a, b); if (mid <= a)//右子树 return query(p*2+1, a, b); //左右子树都有包含的时候 long t1 = query(p*2, a, mid); long t2 = query(p*2+1, mid, b); return t1 < t2 ? t1 : t2; } int main() { long temp; while (scanf("%ld%ld", &N, &M) != EOF) { build(1, 0, N);//0 到 40建树 ,1为 初始下标 S = 1; Val = 0; update(1); while (M--) { scanf("%ld%ld", &temp, &S); Val = query(1, temp - 1, S - 1) + 1;//temp-1是因为题是从0开始建树的,s-1是因为搜索s的前一个线段的标志是为多少 update(1);//从下标1的地方 开始更新 } printf("%ld\n", query(1, N - 1, N)); } return 0; }