(Relax 线段树1.2)POJ 2528 Mayor's posters(计算可见线段)

来源:互联网 发布:淘宝手机开店认证步骤 编辑:程序博客网 时间:2024/06/15 15:29



/* * POJ_2528.cpp * *  Created on: 2013年11月25日 *      Author: Administrator */#include <iostream>#include <cstdio>#include <algorithm>#define maxn 10010#define Fup(i, s, t) for (int i = s; i <= t; i ++)using namespace std;bool tab[maxn];int l[maxn], r[maxn], x[maxn * 3], num[maxn * 3], tree[maxn * 12];int c, n;int binary_search(int sum) {int l = 1, r = 3 * n;while (r >= l) {int mid = (l + r) / 2;if (x[mid] <= sum)l = mid + 1;elser = mid - 1;}return num[r];}void update(int i) {if (!tree[i])return;tree[i + i] = tree[i + i + 1] = tree[i];tree[i] = 0;}void change(int tl, int tr, int l, int r, int i, int co) {if (tr < l || tl > r)return;if (tl <= l && r <= tr) {tree[i] = co;return;}update(i);int mid = (l + r) / 2;change(tl, tr, l, mid, i + i, co);change(tl, tr, mid + 1, r, i + i + 1, co);}int require(int l, int r, int i) {int mid = (l + r) / 2;if (tree[i]) {if (!tab[tree[i]]) {tab[tree[i]] = 1;return 1;}return 0;}if (l == r)return 0;return require(l, mid, i + i) + require(mid + 1, r, i + i + 1);}void init() {scanf("%d", &n);Fup(i, 1, n){scanf("%d%d", l + i, r + i);x[i + i + i - 2] = l[i];x[i + i + i - 1] = r[i];x[i + i + i] = (l[i] + r[i]) / 2;}sort(x + 1, x + 3 * n + 1);memset(num, 0, sizeof(num));Fup(i, 1, 3 * n){num[i] = num[i - 1];if (x[i] != x[i - 1])num[i]++;}Fup(i, 1, n){l[i] = binary_search(l[i]);r[i] = binary_search(r[i]);}}void solve(){memset(tree,0,sizeof(tree));memset(tab,0,sizeof(tab));int i;for(i = 1 ; i <= n ; ++i){change(l[i],r[i],1,3*n,1,i);}int ans = require(1,3*n,1);printf("%d\n",ans);}int main(){scanf("%d",&c);while(c--){init();solve();}return 0;}


原创粉丝点击