• BZOJ5168:[HAOI2014]贴海报(线段树)


    Description

    Bytetown城市要进行市长竞选,所有的选民可以畅所欲言地对竞选市长的候选人发表言论。为了统一管理,城市委
    员 会为选民准备了一个张贴海报的electoral墙。张贴规则如下:
    1.electoral墙是一个长度为N个单位的长方形,每个单位记为一个格子;
    2.所有张贴的海报的高度必须与electoral墙的高度一致的;
    3.每张海报以“A B”表示,即从第A个格子到第B个格子张贴海报;
    4.后贴的海报可以覆盖前面已贴的海报或部分海报。
    现在请你判断,张贴完所有海报后,在electoral墙上还可以看见多少张海报。

    Input

    第一行: N M 分别表示electoral墙的长度和海报个数
    接下来M行: Ai Bi 表示每张海报张贴的位置

    Output

    输出贴完所有海报后,在electoral墙上还可以看见的海报数。
    1 0<= N <= 10000000 1<=M<=1000 1<= Ai <= Bi <=10000000
    所有的数据都是整数。数据之间有一个空格

    Sample Input

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

    Sample Output

    4

    Solution

    裸的线段树区间覆盖的题目,覆盖一下最后统计一波就好了

    Code

     1 #include<iostream>
     2 #include<cstring>
     3 #include<cstdio>
     4 #include<algorithm>
     5 #define N (1000000+100)
     6 using namespace std;
     7 
     8 int Segt[N<<2];
     9 int n,m,x[N],y[N],id[N],cnt,num,ans;
    10 bool vis[N];
    11 
    12 void Pushdown(int now)
    13 {
    14     if (Segt[now])
    15     {
    16         Segt[now<<1]=Segt[now];
    17         Segt[now<<1|1]=Segt[now];
    18         Segt[now]=0;
    19     }
    20 }
    21 
    22 void Update(int now,int l,int r,int l1,int r1,int k)
    23 {
    24     if (l>r1 || r<l1) return;
    25     if (l1<=l && r<=r1){Segt[now]=k; return;}
    26     Pushdown(now);
    27     int mid=(l+r)>>1;
    28     Update(now<<1,l,mid,l1,r1,k);
    29     Update(now<<1|1,mid+1,r,l1,r1,k);
    30 }
    31 
    32 int Query(int now,int l,int r,int x)
    33 {
    34     if (l==r) return Segt[now];
    35     Pushdown(now);
    36     int mid=(l+r)>>1;
    37     if (x<=mid) return Query(now<<1,l,mid,x);
    38     else return Query(now<<1|1,mid+1,r,x);
    39 }
    40 
    41 int getid(int x)
    42 {
    43     int l=1,r=num;
    44     while (l<=r)
    45     {
    46         int mid=(l+r)>>1;
    47         if (id[mid]==x) return mid;
    48         if (x<id[mid]) r=mid-1;
    49         else l=mid+1;
    50     }
    51 }
    52 
    53 int main()
    54 {
    55     scanf("%d%d",&n,&m);
    56     for (int i=1; i<=m; ++i)
    57     {
    58         scanf("%d%d",&x[i],&y[i]);
    59         id[++cnt]=x[i], id[++cnt]=y[i];
    60         id[++cnt]=x[i]+1,id[++cnt]=y[i]+1;//离散化的时候加入一个点两边的位置 
    61         id[++cnt]=x[i]-1,id[++cnt]=y[i]-1;//不这样会挂 
    62     }
    63     sort(id+1,id+cnt+1);
    64     num=unique(id+1,id+cnt+1)-id-1;
    65     for (int i=1; i<=m; ++i)
    66     {
    67         int xx=getid(x[i]),yy=getid(y[i]);
    68         Update(1,1,num,xx,yy,i);
    69     }
    70     for (int i=1; i<=num; ++i)
    71     {
    72         int t=Query(1,1,num,i);
    73         if (t && !vis[t]) ans++;
    74         vis[t]=true;
    75     }
    76     printf("%d",ans);
    77 }
  • 相关阅读:
    修改文件小练习
    登录、注册、删除小练习
    自动生成用户名和密码
    自动生成密码文件
    监控日志被攻击情况-小练习
    随机函数_手机自动生成小练习
    as与c++的反射机制对比
    as中的陷阱
    关于as中的事件与回调函数
    身份证号码验证
  • 原文地址:https://www.cnblogs.com/refun/p/8971033.html
Copyright © 2020-2023  润新知