Mayor's posters 线段树区间覆盖
Posted mmmqqdd
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Mayor's posters 线段树区间覆盖相关的知识,希望对你有一定的参考价值。
题目链接
http://poj.org/problem?id=2528
Description
- Every candidate can place exactly one poster on the wall.
- All posters are of the same height equal to the height of the wall; the width of a poster can be any integer number of bytes (byte is the unit of length in Bytetown).
- The wall is divided into segments and the width of each segment is one byte.
- Each poster must completely cover a contiguous number of wall segments.
They have built a wall 10000000 bytes long (such that there is enough place for all candidates). When the electoral campaign was restarted, the candidates were placing their posters on the wall and their posters differed widely in width. Moreover, the candidates started placing their posters on wall segments already occupied by other posters. Everyone in Bytetown was curious whose posters will be visible (entirely or in part) on the last day before elections.
Your task is to find the number of visible posters when all the posters are placed given the information about posters‘ size, their place and order of placement on the electoral wall.
Input
There will be several test cases in the input. Each test case consists of N + 1 lines where N (1 ≤ N ≤ 200,000) is given in the first line of the test case. The next N lines contain the pairs of values Posi and Vali in the increasing order of i (1 ≤ i ≤ N). For each i, the ranges and meanings of Posi and Vali are as follows:
- Posi ∈ [0, i − 1] — The i-th person came to the queue and stood right behind the Posi-th person in the queue. The booking office was considered the 0th person and the person at the front of the queue was considered the first person in the queue.
- Vali ∈ [0, 32767] — The i-th person was assigned the value Vali.
There no blank lines between test cases. Proceed to the end of input.
Output
The picture below illustrates the case of the sample input.
Sample Input
5
1 4
2 6
8 10
3 4
7 10
Sample Output
HINT
题意
一个区间按照顺序贴n海报,海报高都为1,位置为(l,r),表示海报的位置和长度。
最后问你在最后,能看见多少个海报(即没有被其他海报完全覆盖)。
题解:
这题就是区间覆盖,区间修改,最后将标记全部下放到底,扫一遍叶子节点就好了。
需要注意的是离散化时对于区间(l,r),需要加入l,l+1,r,r+1四个点离散。
如果只离散左右端点,比如 (1,3) (3,10) (10,13) 三个海报离散后,就成了(1,2) (2,3) (3, 4),这样(2,3)就没有了。
代码:
1 #include<cstdio> 2 #include<iostream> 3 #include<algorithm> 4 #include<cstring> 5 using namespace std; 6 #define N 100050 7 int n,cnt,num,ans,kth[N<<1],f[N]; 8 struct Query{int l,r;}que[N]; 9 struct Tree{int l,r,val;}tr[N<<2]; 10 template<typename T>void read(T&x) 11 { 12 int k=0;char c=getchar(); 13 x=0; 14 while(!isdigit(c)&&c!=EOF)k^=c==‘-‘,c=getchar(); 15 if (c==EOF)exit(0); 16 while(isdigit(c))x=x*10+c-‘0‘,c=getchar(); 17 x=k?-x:x; 18 } 19 void push_down(int x) 20 { 21 if (tr[x].val==0)return ; 22 Tree &a=tr[x<<1],&b=tr[x<<1|1]; 23 a.val=tr[x].val; 24 b.val=tr[x].val; 25 tr[x].val=0; 26 } 27 void bt(int x,int l,int r) 28 { 29 ++num; 30 tr[x]={l,r,0}; 31 if (l==r)return; 32 int mid=(l+r)>>1; 33 bt(x<<1,l,mid); 34 bt(x<<1|1,mid+1,r); 35 } 36 void update(int x,int l,int r,int tt) 37 { 38 if (l<=tr[x].l&&tr[x].r<=r) 39 { 40 tr[x].val=tt; 41 return; 42 } 43 int mid=(tr[x].l+tr[x].r)>>1; 44 push_down(x); 45 if (l<=mid)update(x<<1,l,r,tt); 46 if (mid<r)update(x<<1|1,l,r,tt); 47 } 48 void query(int x) 49 { 50 if (tr[x].l==tr[x].r) 51 { 52 int tt=f[tr[x].val]==0; 53 ans+=tt; 54 f[tr[x].val]=1; 55 return; 56 } 57 int mid=(tr[x].l+tr[x].r)>>1; 58 push_down(x); 59 query(x<<1); 60 query(x<<1|1); 61 } 62 void clear() 63 { 64 num=0; ans=0; cnt=0; 65 memset(f,0,sizeof(f)); 66 } 67 void input() 68 { 69 read(n); 70 for(int i=1;i<=n;i++) 71 { 72 read(que[i].l);read(que[i].r); 73 kth[++cnt]=que[i].l; 74 kth[++cnt]=que[i].r; 75 kth[++cnt]=que[i].l+1; 76 kth[++cnt]=que[i].r+1; 77 } 78 sort(kth+1,kth+cnt+1); 79 cnt=unique(kth+1,kth+cnt+1)-kth-1; 80 bt(1,1,cnt); 81 } 82 void work() 83 { 84 85 for(int i=1;i<=n;i++) 86 { 87 int l=lower_bound(kth+1,kth+cnt+1,que[i].l)-kth; 88 int r=lower_bound(kth+1,kth+cnt+1,que[i].r)-kth; 89 update(1,l,r,i); 90 } 91 f[0]=1; 92 /* for(int x=1;x<=n*8;x++) 93 if (tr[x].l==tr[x].r) 94 { 95 ans+=f[tr[x].val]==0; 96 f[tr[x].val]=1; 97 } 98 else push_down(x); 99 */ 100 query(1); 101 printf("%d ",ans); 102 } 103 int main() 104 { 105 #ifndef ONLINE_JUDGE 106 freopen("aa.in","r",stdin); 107 #endif 108 int q; 109 read(q); 110 while(q--) 111 { 112 clear(); 113 input(); 114 work(); 115 } 116 }
以上是关于Mayor's posters 线段树区间覆盖的主要内容,如果未能解决你的问题,请参考以下文章
Mayor's posters POJ - 2528 线段树区间覆盖
POJ 2528 Mayor's posters (线段树区间更新+离散化)
POJ 2528 Mayor's posters(线段树区间染色+离散化或倒序更新)
POJ 2528 Mayor's posters (线段树 离散化+区间更新+区间求值 )