• 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);
    }
    
  • 相关阅读:
    __setattr__,__getattr__,__delattr__
    LeetCode 面试题42. 连续子数组的最大和
    LeetCode 53. 最大子序和
    LeetCode 面试题39. 数组中出现次数超过一半的数字
    LeetCode 169. 多数元素
    LeetCode 426.将二叉搜索树转化为排序的双向链表
    LeetCode 面试题36. 二叉搜索树与双向链表
    LeetCode 面试题35. 复杂链表的复制
    LeetCode 138. 复制带随机指针的链表
    LeetCode 面试题34. 二叉树中和为某一值的路径
  • 原文地址:https://www.cnblogs.com/Lance1ot/p/9220023.html
Copyright © 2020-2023  润新知