线段树之离散化

POJ - 2528

离散化是将有用的信息提取出来,在区间很大的时候,用直接用线段树肯定会超时,但由于在区间内很大值是没有用到的,只把有用的区间提取出来再用线段数做就方便多了。

 1 #include <iostream>
 2 #include <stdio.h>
 3 #include <string.h>
 4 #include <algorithm>
 5 #define lson l,m,rt<<1
 6 #define rson m+1,r,rt<<1|1
 7 using namespace std;
 8 const int MAX = 11111;
 9 int col[MAX<<4],li[MAX],ri[MAX],x[MAX*3],ans;
10 bool hash[MAX];
11 void PushDown(int rt){
12     if(col[rt] != -1){
13         col[rt<<1] = col[rt<<1|1] = col[rt];
14         col[rt] = -1;
15     }
16 }
17 void update(int LL, int RR, int c, int l, int r, int rt){
18     if(LL <= l && r <= RR){
19         col[rt] = c;
20         return;
21     }
22     PushDown(rt);
23     int m = (l+r)>>1;
24     if(LL <= m)update(LL,RR,c,lson);
25     if(m < RR) update(LL,RR,c,rson);
26 }
27 void query(int l, int r, int rt){
28     if(col[rt] != -1){
29         if(!hash[col[rt]])ans++;
30         hash[col[rt]] = true;
31         return;
32     }
33     if(l == r)return;
34     int m = (l+r)>>1;
35     query(lson);
36     query(rson);
37 }
38 int Bin(int key,int len){
39     int l = 0, r = len-1;
40     while(l <= r){
41         int m = (l+r)>>1;
42         if(x[m] == key)return m;
43         if(x[m] > key)r = m-1;
44         else l = m+1;
45     }
46     return -1;
47 }
48 int main(){
49     int t,n;
50     scanf("%d",&t);
51     while(t--){
52         scanf("%d",&n);
53         int nn = 0;
54         for(int i = 0; i < n; i ++){
55             scanf("%d %d",&li[i],&ri[i]);
56             x[nn++] = li[i];x[nn++] = ri[i];
57         }
58         sort(x,x+nn);
59         int m = 1;
60         for(int i = 1; i < nn; i ++){
61             if(x[i]!=x[i-1])x[m++] = x[i];
62         }
63         for(int i = m-1; i > 0; i --){
64             if(x[i] != x[i-1]+1)x[m++] = x[i-1]+1;
65         }
66         sort(x,x+m);
67         memset(col,-1,sizeof(col));
68         for(int i = 0; i < n; i ++){
69             int l = Bin(li[i],m);
70             int r = Bin(ri[i],m);
71             update(l,r,i,0,m,1);
72         }
73         ans = 0;
74         memset(hash,false,sizeof(hash));
75         query(0,m,1);
76         printf("%d\n",ans);
77     }
78     return 0;
79 }

 

posted @ 2017-07-14 10:55  starry_sky  阅读(258)  评论(0编辑  收藏  举报