一道线段树 + 离散化的题,因为搞错了建树的L和R卡了一会儿。
其实不用建树的,只是我比较习惯写带结构体的线段树。。。
线段树还是没完全搞懂,先把这题放在这里作为记录。
ac代码
#include <iostream> #include <algorithm> #include <vector> using namespace std; typedef long long ll; const int maxn = 2e5 + 5; struct node { int l, r, val; }tree[maxn << 2]; node arr[maxn << 2]; int Hash[maxn << 2]; int vis[maxn << 2]; void build(int l, int r, int k) { tree[k].l = l; tree[k].r = r; if (l == r) return; int mid = (l + r) >> 1; build(l, mid, k << 1); build(mid + 1, r, k << 1 | 1); return; } void pushdown(int k) { tree[k << 1].val = tree[k << 1 | 1].val = tree[k].val; tree[k].val = 0; } void updata(int l, int r, int k, int c) { if (l <= tree[k].l && r >= tree[k].r) { tree[k].val = c; return; } if (tree[k].val != 0) pushdown(k); int mid = (tree[k].l + tree[k].r) >> 1; if (l > mid) updata(l, r, k << 1 | 1, c); else if (r <= mid) updata(l, r, k << 1, c); else { updata(l, r, k << 1, c); updata(l, r, k << 1 | 1, c); } return; } int ans = 0; void query(int k) { if (tree[k].val != 0) { if (!vis[tree[k].val]) { ans++; vis[tree[k].val] = 1; } return; } if (tree[k].l == tree[k].r) return; query(k << 1); query(k << 1 | 1); } int main() { int q; scanf("%d", &q); while (q--) { memset(tree, 0, sizeof(tree)); memset(arr, 0, sizeof(arr)); memset(vis, 0, sizeof(vis)); int n; scanf("%d", &n); int len = 0; for (int i = 0; i < n; i++) { scanf("%d %d", &arr[i].l, &arr[i].r); Hash[len++] = arr[i].l; Hash[len++] = arr[i].r; } sort(Hash, Hash + len); int m = unique(Hash, Hash + len) - Hash; int t = m; for (int i = 1; i < t; i++) { if (Hash[i] - Hash[i - 1] > 1) Hash[m++] = Hash[i - 1] + 1; } sort(Hash, Hash + m); build(0, m - 1, 1); for (int i = 0; i < n; i++) { int x = lower_bound(Hash, Hash + m, arr[i].l) - Hash; int y = lower_bound(Hash, Hash + m, arr[i].r) - Hash; updata(x, y, 1, i + 1); } ans = 0; query(1); printf("%d ", ans); } return 0; }