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);
}
原文地址:https://www.cnblogs.com/Lance1ot/p/9220023.html