poj2528 (线段树+离散化)

传送门::http://poj.org/problem?id=2528

题意: 在墙上贴海报,海报可以互相覆盖,问最后可以看见几张海报

数据:1 <= i <= n, 1 <= li <= ri <= 10000000;1 <= n <= 10000

思路:离散化+线段树

离散化 定义::把无限空间中有限的个体映射到有限的空间中去,以此提高算法的时空效率。(by百度百科)

 通俗点说就是 在不改变数据的可用性质下缩小其范围,一般只关注他们的相对大小

但对于本题而言普通离散化不行,我们还要维护一个性质,那就是是否相邻,举个例子就会明白

[1,5] [1,2] [4,5]离散后[1,4] [1,2][3,4]这样做的答案为2(原因就是二三区间归为一起,导致覆盖第一区间),而实际上答案为3

那我们应该在差值大于1的两个数之间插入一个数,避免相邻的归为一个区间

所以  离散化两性质:大小关系和是否相邻

线段树:

只需开一个数组来标记出现过的颜色即可

 1 //#include<bits/stdc++.h>
 2 #include<stdio.h>
 3 #include<algorithm>
 4 #include<string.h>
 5 #include<string>
 6 #include<iostream>
 7 #define ll long long
 8 const int maxn=1e5+5;
 9 using namespace std;
10 
11 int a[maxn],b[maxn],c[maxn*2];
12 int lazy[maxn<<2];
13 bool use[maxn<<2];
14 int ans;
15 
16 void pushdown(int rt)
17 {
18     if(lazy[rt]){
19         lazy[2*rt]=lazy[2*rt+1]=lazy[rt];
20         lazy[rt]=0;
21     }
22 }
23 void update(int L,int R,int l,int r,int rt,int add)
24 {
25     if(L<=l&&R>=r){
26         lazy[rt]=add;
27         return ;
28     }
29     int mid=(l+r)>>1;
30     pushdown(rt);
31     if(L<=mid){
32         update(L,R,l,mid,2*rt,add);
33     }
34     if(R>mid){
35         update(L,R,mid+1,r,2*rt+1,add);
36     }
37 }
38 void query(int L,int R ,int l,int r,int rt)
39 {
40     if(lazy[rt]!=0){
41         if(!use[lazy[rt]])ans++;
42         use[lazy[rt]]=1;
43         return ;
44     }
45     if(l==r){return ;}
46     int mid=(l+r)>>1;
47     if(L<=mid){
48         query(L,R,l,mid,2*rt);
49     }
50     if(R>mid){
51         query(L,R,mid+1,r,2*rt+1);
52     }
53 }
54 int main()
55 {
56     int t,k,m;
57     scanf("%d",&t);
58     while(t--){
59     m=ans=0;
60     memset(use,0,sizeof(use));
61     memset(lazy,0,sizeof(lazy));
62     scanf("%d",&k);
63     for(int i=1;i<=k;i++)
64     {
65         scanf("%d%d",&a[i],&b[i]);
66         c[++m]=a[i];c[++m]=b[i];
67     }
68     sort(c+1,c+m+1);
69     m=unique(c+1,c+m+1)-c;
70     m--;
71     for(int i=m;i>1;i--)
72     {
73         if(c[i]-1>c[i-1]){
74             c[++m]=c[i-1]+1;
75         }
76     }
77     sort(c+1,c+m+1);
78     m=unique(c+1,c+m+1)-c;
79     for(int i=1;i<=k;i++){
80         a[i]=lower_bound(c+1,c+m,a[i])-c;
81         b[i]=lower_bound(c+1,c+m,b[i])-c;
82         update(a[i],b[i],1,m-1,1,i);
83     }
84     query(1,m-1,1,m-1,1);
85     cout<<ans<<endl;
86     }
87     return 0;
88 }
View Code

 

posted @ 2019-11-01 20:12  sj-_-js  阅读(134)  评论(0编辑  收藏  举报