Mayor's posters(线段树区间更新)

描述

转自我的博客
传送门:poj-2528
一样的题:swustoj-764(校门外的树 Plus Plus)

 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

The first line of input contains a number c giving the number of cases that follow. The first line of data for a single case contains number 1 <mtext>   </mtext> &lt; = <mtext>   </mtext> n <mtext>   </mtext> &lt; = <mtext>   </mtext> 10000 1\ &lt;=\ n\ &lt;=\ 10000 1 <= n <= 10000. The subsequent n lines describe the posters in the order in which they were placed. The i t h i^{th} ith line among the n lines contains two integer numbers l i l_i li and r i r_i ri which are the number of the wall segment occupied by the left end and the right end of the i t h i^{th} ith poster, respectively. We know that for each 1 <mtext>   </mtext> &lt; = <mtext>   </mtext> i <mtext>   </mtext> &lt; = <mtext>   </mtext> n 1\ &lt;=\ i\ &lt;=\ n 1 <= i <= n, 1 &lt; = l i &lt; = r i &lt; = 10000000 1 &lt;= l_i &lt;= r_i &lt;= 10000000 1<=li<=ri<=10000000. After the i t h i^{th} ith poster is placed, it entirely covers all wall segments numbered l i , l i + 1 , . . . , r i l_i, l_{i+1} ,... , r_i li,li+1,...,ri.

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.

Examples

  • intput
1
5
1 4
2 6
8 10
3 4
7 10
  • output
4

题目大意

n n n张海报要贴到墙上,按张贴顺序给出了每张海报贴的起始位置(只考虑横坐标),求最后能看到的海报的数量(只要有一点能看到就算能看到)。

思路

  • 很明显要用线段树,维护区间是否被覆盖了。
  • 我们可以很显然想到,应该倒序覆盖区间,因为最后面贴的一定是看得到的。
  • 每次覆盖的时候判断是否需要更新区间的状态。也就是说,如果你即将覆盖的区域已经(由于之前的覆盖操作)完全被覆盖了,那么就不需要更新这个区间的状态了。相当于是你现在要贴的海报会被后面要贴的海报所完全覆盖,那么你现在要贴的这张海报最后就看不到了。
  • 每次覆盖的时候,如果需要更新区间,那么ans++,详见代码。

代码

#include<iostream>
#include<string.h>
using namespace std;
#define rep(i,a,n) for(int i=a;i<n;i++)
#define repd(i,a,n) for(int i=a;i>=n;i--)
#define CRL(a) memset(a,0,sizeof(a))
const int N=1e7+5;
bool tr[N<<2];
struct node {int l,r;}Op[10005];    //储存操作

bool Update(int root,int l,int r,int ul,int ur){//覆盖函数,true:需要更新 false:不需要更新
    if(tr[root]) return false;          //如果当前区间已经完全被覆盖了,就返回false
    
    if(ul==l&&ur==r) return tr[root]=true;  //刚好为要覆盖的区间,更新! 返回true
    
    //线段树常规操作,递归处理
    bool ret; int mid=l+r>>1;   
    if(ur<=mid)      ret=Update(root<<1,l,mid,ul,ur);
    else if(ul>mid)  ret=Update(root<<1|1,mid+1,r,ul,ur);
    else{
        bool ans1=Update(root<<1,l,mid,ul,mid);
        bool ans2=Update(root<<1|1,mid+1,r,mid+1,ur);
        ret=ans1||ans2; //只要有一边需要更新就返回true
    }   
    
    if(tr[root<<1]&&tr[root<<1|1]) tr[root]=true;//如果更新完后这个区间的子区间都被覆盖了,他也被覆盖
    return ret;
}

int main()
{
    std::ios::sync_with_stdio(false);   //关闭流同步,加速cin,cout
    int n,l,r,ans=0,Max,T;
    cin>>T;
    while(T--){
        cin>>n;
        CRL(tr);ans=Max=0;
        rep(i,0,n) {
            cin>>Op[n-i-1].l>>Op[n-i-1].r;  //倒着存操作
            Max=max(Max,Op[n-i-1].r);       //维护最大的横坐标
        }

        rep(i,0,n)                      //依次覆盖
            if(Update(1,1,Max,Op[i].l,Op[i].r)) //如果需要更新,ans++
                ans++;
    
        cout<<ans<<endl;
    }
    return 0;
}
全部评论

相关推荐

不愿透露姓名的神秘牛友
05-29 15:00
教授A:“你为什么要讲这么久,是要压缩我们对你的评议时间吗?你们别以为这样就能够让我们对你们少点意见。”&nbsp;“从你的发言和论文格式就能知道你的性格啊。”…….&nbsp;感觉被狠狠霸凌了。
码农索隆:“教授您好,首先我想回应您提出的两点疑问。” “关于我讲解时间较长的问题:这绝非为了压缩各位老师的评议时间。这份毕业设计是我过去几个月倾注了全部心血的作品,从构思、实验、调试到撰写,每一个环节都反复打磨。我深知时间宝贵,所以选择详细讲解,是希望能更完整、清晰地展示它的核心创新点、实现过程和验证结果,确保老师们能充分理解它的价值和我的努力。我完全理解并重视评审环节的意义,也做好了充分准备来听取各位老师的专业意见和批评。几个月的研究都坚持下来了,我怎么可能害怕老师们的点评呢?今天站在这里,正是抱着虚心学习、诚恳求教的态度而来。” “如果我的展示确实超时,影响了后续流程,烦请老师们随时示意,我会立刻调整。我非常期待并预留了充足的时间,希望能听到老师们宝贵的建议和深入的讨论。” “其次,关于您提到‘从发言和论文格式就能知道我的性格’。教授,我对此感到非常困惑和不安。学术研究和答辩的核心,难道不应该是作品本身的质量、逻辑的严谨性、数据的可靠性和结论的合理性吗?论文格式有明确的规范要求,我尽最大努力遵循了这些规范。如果格式上存在疏忽或不足,这属于技术性、规范性的问题,恳请老师们具体指出,我一定认真修改。但将格式问题或个人表达风格(如讲解时长)直接上升为对个人性格的评判,甚至以此作为质疑我学术态度和动机的依据,这让我感到非常不公平,也偏离了学术评议应有的客观和严谨原则。” “我尊重每一位评审老师的专业权威,也衷心希望能得到老师们对我的工作内容本身的专业指导和批评指正。任何基于研究本身的意见,无论多么尖锐,我都会认真聆听、反思并改进。但我恳请老师们,能将评议的焦点放在我的研究本身,而不是对我个人进行主观的推断或评价。谢谢各位老师。”
点赞 评论 收藏
分享
ResourceUtilization:四六级不愧是大学最有用的证之一
点赞 评论 收藏
分享
吴offer选手:HR:我KPI到手了就行,合不合适关我什么事
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客企业服务