离散化+线段树 poj2528

来源:互联网 发布:高考志愿填报软件 编辑:程序博客网 时间:2024/05/17 01:07
//离散化+线段树#include <cstdio>#include <cstring>#include <algorithm>#define CLR(A) memset(A,0,sizeof(A))using namespace std;const int N = 20005;int col[N * 4], vis[N];int le[N], ri[N], c[N * 2], ans;void pushdown(int p){if (col[p] == -1) return;col[p << 1] = col[p << 1 | 1] = col[p];col[p] = -1;}void update(int p, int s, int e, int l, int r, int v){if (s >= l && e <= r){col[p] = v;return;}pushdown(p);if (l <= (s+e)>>1) update(p<<1,s,((s+e)>>1), l, r, v);if (r > (s+e)>>1) update(p<<1|1,((s+e)>>1)+1,e, l, r, v);}void query(int p, int s, int e){if (col[p] != -1){if (!vis[col[p]])vis[col[p]] = 1, ++ans;return;}query(p << 1, s, (s+e)>>1);query(p << 1 | 1, ((s+e)>>1) + 1,e);}int compress(int n) //离散化{int k = 0;for (int i = 0; i < n; ++i){c[k++] = le[i];c[k++] = ri[i];c[k++] = ri[i] + 1;}sort(c, c + k);return unique(c, c + k) - c - 1;}int main(){int cas, m, n, l, r;scanf("%d", &cas);while (cas--){scanf("%d", &m);for (int i = 0; i < m; ++i)scanf("%d%d", &le[i], &ri[i]);n = compress(m);ans = 0;CLR(col), CLR(vis);for (int i = 0; i < m; ++i){l = lower_bound(c, c + n, le[i]) - c + 1;r = lower_bound(c, c + n, ri[i]) - c + 1;update(1, 1, n, l, r, i + 1);}vis[0] = 1;query(1, 1, n);printf("%d\n", ans);}return 0;}

原创粉丝点击