#include #include using namespace std; const int MAXN = 100014; int n, m; int lazy[MAXN << 2]; int num[MAXN << 2]; int left1[MAXN]; int right1[MAXN]; bool vis[MAXN]; int ans = 0;
int ls(int id) { return id << 1; } int rs(int id) { return id << 1 | 1; }
//本题并没有定义线段树区间代表什么,所以build函数并没有实际意义 void build(int id, int l, int r) { if (l == r) { return; } int mid = (l + r) >> 1; build(ls(id), l, mid); build(rs(id), mid + 1, r); }
void pushdown(int id, int l, int r) { if (lazy[id] == 0) { //标记为0代表id区间并没有张贴海报,当然只是说该区间没有,要知道线段树中有很多区间,大区间中也有很多小区间,这点需要明确,并不是线性表,并不是线性表,并不是线性表,重要的事情说三遍 return ; } //将该标记向下传递给跟小区间,相当于再次张贴海报将原有海报覆盖 lazy[ls(id)] = lazy[id]; lazy[rs(id)] = lazy[id]; //删除标记 lazy[id] = 0; }
void update(int id, www.laipuhuo.com.int l, int r, int p, int q, int v) { if (l >= p && r <= q) { lazy[id] = v; //v就是上文说到的编号 return; } pushdown(id, l, r); //向下覆盖 int mid = (l + r) >> 1; //直到将张贴的海报的区间所覆盖的所有节点区间覆盖 if (p <= mid) update(ls(p), l, mid, p, q, v); if (q > mid) update(rs(p), mid + 1, r, p, q, v); }
void query(int id, int l, int r) { if (lazy[id] && !vis[lazy[id]]) { vis[lazy[id]] = 1; //这个数组一开始全是零 ans++; return; } //注意这个判断为什么写在这里 if (l == r) { return; } pushdown(id, l, r); int mid = l + r; query(ls(id), l, mid); query(rs(id), mid + 1, r); }
int main() { int t; cin >> t; while (t--)www.laipuhuo.com. { ans = 0; memset(lazy, 0, sizeof(lazy)); memset(vis, 0, sizeof(vis)); cin >> n; int cnt = 1; for (int i = 1; i <= n; i++) { int a, b; cin >> left1[i]www.laipuhuo.com. >> right1[i]; num[cnt++] = left1[i]; num[cnt++] = right1[i]; } //先排序一次,以便第一次去重 sort(num + 1, num + cnt); m = unique(num + 1, num + cnt) - (num + 1); int an = m; for (int i = 2; i <= m; i++) { if (num[i] - num[i - 1] > 1) { num[++an] = num[i - 1] + 1; //加入中间元素,避免上文提到的离散化出现的错误 } } //重新排序后,加入的中间元素回自动被插入到相应位置 sort(num + 1, num + an + 1); build(1, 1, an); for (int i = 1; i <= n; i++) { int p = lower_bound(num + 1, num + an + 1, left1[i]) - num; int q = www.laipuhuo.com.lower_bound(num + 1, num + an + 1, right1[i]) - num; update(1, 1, an, p, q, i); } query(1, 1, an); cout << ans << endl; } return 0; }