zoukankan      html  css  js  c++  java
  • Mayor's posters 线段树区间覆盖

    题目链接

    http://poj.org/problem?id=2528

    Description

    The citizens of Bytetown, AB, could not stand that the candidates in the mayoral election campaign have been placing their electoral posters at all places at their whim. The city council has finally decided to build an electoral wall for placing the posters and introduce the following rules:
    • 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 ≤ iN). 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

    For each input data set print the number of visible posters after all the posters are placed.

    The picture below illustrates the case of the sample input.
     

    Sample Input

    1
    5
    1 4
    2 6
    8 10
    3 4
    7 10

    Sample Output

    4

    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)就没有了。

    提供一个下载本题数据的网站:https://webdocs.cs.ualberta.ca/~acpc/2003/

    代码:

      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 }
    View Code
  • 相关阅读:
    操作系统原理
    Linux三剑客正则表达式
    Linux通配符知识深度实践详解
    Linux文件属性之时间戳及文件名知识详解
    Linux系统文件权限
    date:显示与设置系统时间
    正则表达式--三剑客简单应用
    Linux习题小结
    Linux系统文件属性知识
    Linux系统目录结构知识
  • 原文地址:https://www.cnblogs.com/mmmqqdd/p/10753344.html
Copyright © 2011-2022 走看看