poj 2528 Mayor’s posters 线段树

来源:互联网 发布:宁波淘宝运营高手 编辑:程序博客网 时间:2024/05/30 23:49
//poj 2528 Mayor’s posters////题目大意://给你n张海报,每张海报是一段区间,问最后由几张还好能露出来////解题思路://线段树,别看那海报的区间范围很大,其实那些都没用.n才10000呢//将区间离散化之后,然后在进行线段树的操作,但是注意在相差大于1//的区间中间加上一个值,这样讲两个区间区分开,然后就是基本操作了//挺好想的#include <cstring>#include <algorithm>#include <iostream>#include <cstdio>#include <cmath>#include <string>#include <vector>#include <queue>#define For(x,a,b,c) for (int x = a; x <= b; x += c)#define Ffor(x,a,b,c) for (int x = a; x >= b; x -= c)#define cls(x,a) memset(x,a,sizeof(x))using namespace std;typedef long long ll;const double PI = acos(-1.0);const double EPS = 1e-10;const int MAX_N = 80000;const int INF = 10009;int N,M;int L[MAX_N],R[MAX_N];int a[MAX_N];int cnt;struct IntervalTree{#define ls(x)(x << 1)#define rs(x)(x << 1 | 1)int col[MAX_N<<2];bool isc[MAX_N];void init(){cls(col,-1);cls(isc,0);}void push_down(int rt){if (col[rt]!=-1){col[ls(rt)] = col[rs(rt)] = col[rt];col[rt] = -1;}}void update(int rt,int L,int R,int ql,int qr,int v){if (ql <= L && R <= qr){col[rt] = v;return ;}push_down(rt);int M = (L + R) >> 1;if (ql <= M)update(ls(rt),L,M,ql,qr,v);if (M < qr)update(rs(rt),M+1,R,ql,qr,v);push_down(rt);}void query(int rt,int L,int R){if (col[rt] != -1){if (!isc[col[rt]])cnt++;isc[col[rt]] = 1;return ;}if(L == R) return ;int M = (L + R) >> 1;query(ls(rt),L,M);query(rs(rt),M+1,R);}}it;void input(){scanf("%d",&N);int tot = 1;for (int i = 1;i <= N;i ++){scanf("%d%d",&L[i],&R[i]);a[tot++] = L[i];a[tot++] = R[i];}sort(a+1,a+tot);int m = 2;for (int i = 2;i < tot ; i++){if (a[i] != a[i-1])a[m++] = a[i];}tot = m;for (int i = tot - 1;i >= 2;i --){if (a[i] - a[i-1] > 1)a[m++] = a[i-1] + 1;}tot = m;sort(a + 1, a + tot);it.init();for (int i = 1;i <= N;i ++){int l = lower_bound(a + 1,a + tot, L[i]) - a;int r = lower_bound(a + 1,a + tot, R[i]) - a;it.update(1,1,tot-1,l,r,i);}cnt = 0;it.query(1,1,tot-1);printf("%d\n",cnt);}int main(){int t;//freopen("1.in","r",stdin);scanf("%d",&t);while(t--){input();}        return 0;}

0 0