P3740 贴海报

Posted lance1ot

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了P3740 贴海报相关的知识,希望对你有一定的参考价值。

P3740 贴海报

很显然,这个题是让我们维护一个区间的信息

可以考虑线段树。可是这个题,正向思维可能并不可做。

所以我们考虑逆向思维。

打个比方,你是一名保洁人员。面对已经粘在墙上的,大大小小的广告。你想要将他们撕下来。

而且你是一个有点强迫症的的人(溜

你总是每天快要下班时打扫,而且他们贴小广告的顺序你也都知道。而且特别强迫症地必须按照顺序,一张一张地撕下来。

有可能你撕小广告的时候,一张小广告已经被撕成好多条,但你还是要必须将这几条一起撕下来。

为了消遣,你想知道你一共撕下来多少张小广告(重叠的算一张)

就像这样:技术分享图片

你将最后贴的一张撕下来,变成了这样:

技术分享图片,这就算一次

然后需要离散化

#include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;
const int manx=1100;
int val[manx<<2],tag[manx<<2];
int data[manx<<1],tail;
int base[manx<<1],k;
struct node
{
    int l,r;
};
node line[manx];
void make_base()
{
    int now=-0x7fffffff;
    for(int i=1;i<=tail;i++)
        if(now!=data[i])
        {
            now=data[i];
            base[++k]=now;
        }
    return ;
}
int find(int val)
{
    int l=1,r=k;
    int mid;
    while(l<r)
    {
        mid=(l+r)>>1;
        if(base[mid]<val)   l=mid+1;
        else    r=mid;
    }
    return l;
}
void build(int root,int l,int r)
{
    val[root]=base[r+1]-base[l];
    tag[root]=0;
    if(l==r)    return ;
    int mid=(l+r)>>1;
    build(root<<1,l,mid);
    build(root<<1|1,mid+1,r);
}
void push_down(int root)
{
    if(tag[root])
    {
        val[root<<1]=0;val[root<<1|1]=0;
        tag[root<<1]=1;tag[root<<1|1]=1;
        tag[root]=0;
    }
    return ;
}
void push_up(int root)
{
    val[root]=val[root<<1]+val[root<<1|1];
    return ;
}
int check(int root,int l,int r,int al,int ar)
{
    if(l>ar||r<al)  return 0;
    if(l>=al&&r<=ar)    return val[root];
    int mid=(l+r)>>1;
    push_down(root);
    return  check(root<<1,l,mid,al,ar)+ 
            check(root<<1|1,mid+1,r,al,ar);
}
void updata(int root,int l,int r,int al,int ar)
{
    if(l>ar||r<al)  return ;
    if(l>=al&&r<=ar)
    {
        val[root]=0;
        tag[root]=1;
        return ;
    }
    int mid=(l+r)>>1;
    push_down(root);
    updata(root<<1,l,mid,al,ar);
    updata(root<<1|1,mid+1,r,al,ar);
    push_up(root);
    return ;
}
int main()
{
    int n,m;
    scanf("%d%d",&n,&m);
    int a,b;
    for(int i=1;i<=m;i++)
    {
        scanf("%d%d",&a,&b);
        data[++tail]=a;
        data[++tail]=b+1;
        line[i].l=a;line[i].r=b+1;
    }
    sort(data+1,data+1+tail);
    make_base();
    build(1,1,k-1);
    int ans=0;
    for(int i=m;i>=1;i--)
    {
        int pos1=find(line[i].l),pos2=find(line[i].r);
        if(check(1,1,k-1,pos1,pos2-1))  ans+=1;
        updata(1,1,k-1,pos1,pos2-1);
    }
    printf("%d",ans);
}

以上是关于P3740 贴海报的主要内容,如果未能解决你的问题,请参考以下文章

洛谷P3740 [HAOI2014]贴海报

线段树P3740 [HAOI2014]贴海报

P3740 [HAOI2014]贴海报

P3740 [HAOI2014]贴海报 离散化+线段树

JZYZOJ1537 [haoi2014]贴海报

[HAOI2014]贴海报