(POJ-2528) Mayor's posters (interval coverage + discretization)

Keywords: Algorithm data structure

Title Link: https://vjudge.net/problem/POJ-2528

This question asks how many posters we can see in the end. If we are thinking about it, it will be more troublesome, because we are not sure whether the current poster will be covered by the later poster, but we can be sure that the later poster will not be covered by his previous poster, so we can paste the poster upside down. If the current poster can be seen, The description will not be obscured by the following posters. As for how to query whether it is obscured, this is the interval query problem of segment tree. Because the boundary of the poster given by the title is relatively large, the array cannot be stored directly. We only need to store their relative size relationship, so we need to use discretization.

However, some problems should be paid attention to during discretization, such as three intervals:

1 10

1 4

6 10

The answer is obviously 3, but after discretization, it becomes:

1 4

1 2

3 4

So the answer becomes 2. Why?

Originally, there is an interval between the second poster and the third poster, but after we discretize them, they become adjacent. Therefore, if a large poster includes their interval, it will affect the answer. Therefore, we add an intermediate value between non adjacent numbers before discretization to eliminate this influence, However, because the data of this topic is relatively water, even if you don't consider this situation, you can ac, but I hope you can consider this situation. After all, the data of the next topic may not be so water. The following code is:

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<queue>
using namespace std;
vector<int>alls;
const int N=5e6+10;
int ll[N],rr[N],l[N],r[N],sum[N],lazy[N];
int find(int x)
{
	return (lower_bound(alls.begin(),alls.end(),x)-alls.begin()+1);
}
void pushup(int id)
{
	sum[id]=sum[id<<1]+sum[id<<1|1];
}
void pushdown(int id)
{
	if(lazy[id])
	{
		lazy[id<<1]=lazy[id];
		lazy[id<<1|1]=lazy[id];
		sum[id<<1]=(r[id<<1]-l[id<<1]+1)*lazy[id];
		sum[id<<1|1]=(r[id<<1|1]-l[id<<1|1]+1)*lazy[id];
		lazy[id]=0;
	}
}
void build(int id,int L,int R)
{
	l[id]=L;r[id]=R;sum[id]=0;lazy[id]=0;
	if(L==R) return ;
	int mid=L+R>>1;
	build(id<<1,L,mid);
	build(id<<1|1,mid+1,R);
	pushup(id);
}
void update_interval(int id,int L,int R,int val)
{
	if(l[id]>=L&&r[id]<=R)
	{
		sum[id]=(r[id]-l[id]+1)*val;
		lazy[id]=val;
		return ;
	}
	pushdown(id);
	int mid=l[id]+r[id]>>1;
	if(mid>=L) update_interval(id<<1,L,R,val);
	if(mid+1<=R) update_interval(id<<1|1,L,R,val);
	pushup(id); 
	return ;
}
int query_interval(int id,int L,int R)
{
	if(l[id]>=L&&r[id]<=R) return sum[id];
	pushdown(id);
	int mid=l[id]+r[id]>>1;
	int ans=0;
	if(mid>=L) ans+=query_interval(id<<1,L,R);
	if(mid+1<=R) ans+=query_interval(id<<1|1,L,R);
	return ans;
}
int main()
{
	int T;
	cin>>T;
	while(T--)
	{
		int n;
		alls.clear();
		scanf("%d",&n);
		build(1,1,4*n);
		for(int i=1;i<=n;i++)
		{
			scanf("%d%d",&ll[i],&rr[i]);
			alls.push_back(ll[i]);
			alls.push_back(rr[i]);
		}
		sort(alls.begin(),alls.end());
		alls.erase(unique(alls.begin(),alls.end()),alls.end());
		int len=alls.size();
		//In the discretized array, an intermediate value is added between two adjacent numbers with an interval greater than 1 to eliminate the influence of the interval 
		for(int i=1;i<len;i++)
			if(alls[i]-alls[i-1]>1)
				alls.push_back(alls[i-1]+1);
		sort(alls.begin(),alls.end());//sort 
		alls.erase(unique(alls.begin(),alls.end()),alls.end());//duplicate removal 
		int ans=0;
		for(int i=n;i>=1;i--)
		{
			int l1=find(ll[i]),r1=find(rr[i]);
			if(query_interval(1,l1,r1)!=r1-l1+1)
			{
				ans++;
				update_interval(1,l1,r1,1);
			}
		}
		printf("%d\n",ans);
	}
	return 0;
}

Posted by einamiga on Wed, 22 Sep 2021 05:06:37 -0700