poj 2528 线段树 离散化的小技巧

题意:在墙上贴海报,海报可以互相覆盖,问最后可以看见几张海报
思路:直接搞超时+超内存,需要离散化。
离散化简单的来说就是只取我们需要的值来 用,比如说区间[1000,2000],[1990,2012] 我们用不到[-∞,999][1001,1989][1991,1999][2001,2011][2013,+∞]这些值,所以我只需要 1000,1990,2000,2012就够了,将其分别映射到0,1,2,3,在于复杂度就大大的降下来了
所以离散化要保存所有需要用到的值,排序后,分别映射到1~n,这样复杂度就会小很多很多
而这题的难点在于每个数字其实表示的是一个单位长度(并且一个点),这样普通的离散化会造成许多错误
给出下面两个简单的例子应该能体现普通离散化的缺陷:
1-10 1-4 5-10
1-10 1-4 6-10
为了解决这种缺陷,我们可以在排序后的数组上加些处理,比如说[1,2,6,10]
如果相邻数字间距大于1的话,在其中加上任意一个数字,比如加成[1,2,3,6,7,10],然后再做线段树就好了.

  1 #include<iostream>
  2 #include<string>
  3 #include<algorithm>
  4 #include<cstdlib>
  5 #include<cstdio>
  6 #include<set>
  7 #include<map>
  8 #include<vector>
  9 #include<cstring>
 10 #include<stack>
 11 #include<cmath>
 12 #include<queue>
 13 #define clc(a,b) memset(a,b,sizeof(a))
 14 //#include <bits/stdc++.h>
 15 using namespace std;
 16 #define LL long long
 17 const int maxn=100000;
 18 int vis[maxn<<2];
 19 int ans=0;
 20 int x[maxn];
 21 int hashh[maxn<<2];
 22 struct node
 23 {
 24     int l,r;
 25 } q[maxn];
 26 
 27 void pushdown(int rt)
 28 {
 29     if(vis[rt]!=-1)
 30     {
 31         vis[rt<<1]=vis[rt<<1|1]=vis[rt];
 32         vis[rt]=-1;
 33     }
 34 }
 35 
 36 void update(int L,int R,int c,int l,int r,int rt)
 37 {
 38     if(L<=l&&R>=r)
 39     {
 40         vis[rt]=c;
 41         return;
 42     }
 43     pushdown(rt);
 44     int m=(l+r)>>1;
 45     if(L<=m) update(L,R,c,l,m,rt<<1);
 46     if(R>m) update(L,R,c,m+1,r,rt<<1|1);
 47 }
 48 
 49 void query(int l,int r,int rt)
 50 {
 51     if(vis[rt]!=-1)
 52     {
 53         if(!hashh[vis[rt]])
 54             ans++;
 55         hashh[vis[rt]]=1;
 56         return;
 57     }
 58     if(l==r)
 59         return;
 60     int m=(l+r)>>1;
 61     query(l,m,rt<<1);
 62     query(m+1,r,rt<<1|1);
 63 }
 64 
 65 int main()
 66 {
 67     int n,t;
 68     scanf("%d",&t);
 69     while(t--)
 70     {
 71         int cnt=0;
 72         scanf("%d",&n);
 73         for(int i=0; i<n; i++)
 74         {
 75             scanf("%d%d",&q[i].l,&q[i].r);
 76             x[cnt++]=q[i].l,x[cnt++]=q[i].r;
 77         }
 78         sort(x,x+cnt);
 79         int m=1;
 80         for(int i=1; i<cnt; i++)
 81         {
 82             if(x[i]!=x[i-1])
 83                 x[m++]=x[i];
 84         }
 85         for(int i=m-1; i>=1; i--)
 86             if(x[i]!=x[i-1]+1)
 87                 x[m++]=x[i-1]+1;
 88         sort(x,x+m);
 89         clc(vis,-1);
 90         for(int i=0; i<n; i++)
 91         {
 92             int l=lower_bound(x,x+m,q[i].l)-x;
 93             int r=lower_bound(x,x+m,q[i].r)-x;
 94             update(l,r,i,0,m,1);
 95         }
 96         clc(hashh,0);
 97         ans=0;
 98         query(0,m,1);
 99         printf("%d\n",ans);
100     }
101     return 0;
102 }
View Code

 

posted @ 2016-02-22 12:29  yyblues  阅读(373)  评论(0编辑  收藏  举报