Poj--2528(线段树,离散化技巧)

2014-09-26 21:58:29

思路:这题并不难想,但是离散化是在是坑到我了。解决离散化缺陷的方法是在离散化时判断相邻两数的差是否大于1,如果大于1,则在两个数中间再插入一个数(介于两数之间)

  参考:http://www.cnblogs.com/wuyiqi/archive/2012/03/19/2405885.html

  1 /*************************************************************************
  2     > File Name: p2528.cpp
  3     > Author: Nature
  4     > Mail: 564374850@qq.com
  5     > Created Time: Fri 26 Sep 2014 04:53:35 PM CST
  6 ************************************************************************/
  7 
  8 #include <cstdio>
  9 #include <cstring>
 10 #include <cstdlib>
 11 #include <cmath>
 12 #include <vector>
 13 #include <queue>
 14 #include <iostream>
 15 #include <algorithm>
 16 using namespace std;
 17 typedef long long ll;
 18 #define lpos pos << 1
 19 #define rpos pos << 1|1
 20 #define getmid(l,r) (l + (r - l) / 2)
 21 const int INF = 1 << 29;
 22 const int maxn = 40010;
 23 
 24 int v,tl,tr;
 25 struct node{
 26     int cnt,col;
 27 }tree[maxn << 2];
 28 
 29 void Build_tree(int pos,int l,int r){
 30     memset(tree,0,sizeof(tree));
 31 }
 32 
 33 void Push_down(int pos){
 34     if(tree[pos].col){
 35         tree[lpos].col = tree[rpos].col = tree[pos].col;
 36         tree[lpos].cnt = tree[rpos].cnt = 1;
 37         tree[pos].col = 0;
 38     }
 39 }
 40 
 41 void Update(int pos,int l,int r){
 42     if(tl <= l && r <= tr){
 43         tree[pos].col = v;
 44         tree[pos].cnt = 1;
 45         return;
 46     }
 47     Push_down(pos);
 48     int mid = getmid(l,r);
 49     if(tl <= mid) Update(lpos,l,mid);
 50     if(tr > mid) Update(rpos,mid + 1,r);
 51     if(tree[lpos].col == 0 || tree[rpos].col == 0
 52             || tree[lpos].col != tree[rpos].col)
 53         tree[pos].cnt = 2;
 54 }
 55 
 56 int used[maxn],ans;
 57 
 58 void Query(int pos,int l,int r){
 59     if(tree[pos].col != 0){
 60         if(used[tree[pos].col] == 0)
 61             ++ans;
 62         used[tree[pos].col] = 1;
 63         return;
 64     }
 65     if(l == r)
 66         return;
 67     int mid = getmid(l,r);
 68     if(tree[lpos].cnt >= 1) Query(lpos,l,mid);
 69     if(tree[rpos].cnt >= 1) Query(rpos,mid + 1,r);
 70 }
 71 
 72 int main(){
 73     int l[10010],r[10010],co[10010 << 1],tco[10010 << 2];
 74     int Case,n;
 75     scanf("%d",&Case);
 76     while(Case--){
 77         scanf("%d",&n);
 78         Build_tree(1,1,n << 2);
 79         int k = 0;
 80         for(int i = 0; i < n; ++i){
 81             scanf("%d%d",&l[i],&r[i]);
 82             co[k++] = l[i];
 83             co[k++] = r[i];
 84         }
 85         sort(co,co + k);
 86         int sz = unique(co,co + k) - co;
 87         int p = 1;
 88         tco[0] = co[0];
 89         for(int i = 1; i < sz; ++i){
 90             if(co[i] - co[i - 1] > 1)
 91                 tco[p++] = co[i - 1] + 1;
 92             tco[p++] = co[i];
 93         }
 94         for(int i = 0; i < n; ++i){
 95             l[i] = lower_bound(tco,tco + p,l[i]) - tco + 1;
 96             r[i] = lower_bound(tco,tco + p,r[i]) - tco + 1;
 97         }
 98         for(int i = 0; i < n; ++i){
 99             tl = l[i];
100             tr = r[i];
101             v = i + 1;
102             Update(1,1,n << 2);
103         }
104         ans = 0;
105         memset(used,0,sizeof(used));
106         Query(1,1,n << 2);
107         printf("%d\n",ans);
108     }
109     return 0;
110 }

 

posted @ 2014-09-26 22:03  Naturain  阅读(173)  评论(0)    收藏  举报