[Luogu] P2434 [SDOI2005] interval (ා parallel search / greed)

Posted by freedmania on Wed, 23 Oct 2019 19:59:25 +0200

Title Description

Now we give n closed intervals [ai, bi], 1 < = I < = n. The union of these intervals can be expressed as the union of some disjoint closed intervals. Your task is to find the solution with the least interval in these representations. Your output should be in ascending order of the interval. If the two intervals [a, b] and [c, d] are arranged in ascending order, then we have a < = B < C < = D.

Please write a program:

Read in these intervals;

The disjoint closed interval satisfying the given conditions is calculated.

Output these intervals in ascending order.

I / O format

Input format:

The first line contains an integer n, 3 < = n < = 50000, which is the number of intervals. The following N-BEHAVIOR describes the interval, and the i-behavior describes the i-interval as two integers 1 < = AI < Bi < = 1000000, representing an interval [ai, bi].

Output format:

Output the calculated disjoint interval. Each line is a description of an interval, including two integers separated by spaces, which are the upper and lower bounds of the interval. You should sort the intervals in ascending order.

Example of input and output

Input sample × 1

5
5 6
1 4
10 10
6 9
8 10

Output sample

1 4
5 10

thinking

In the solution, the big guy also said: this problem requires to find out the disjoint interval of a given interval and concentration.

It's easy to think of the greedy way. Here's a simple way to talk about and check the collection. Because we have the operation of finding whether there is intersection between two intervals and whether there is merging interval, we may as well do the same as parallel query.

Greed:

#include <stdio.h>
#include <iostream>
#include <algorithm>
using namespace std;
typedef struct
{
	int l,r;
}lxydl;
lxydl a[50001];
int n,start,end,s;
inline bool cmp(lxydl a,lxydl b)
{
	return a.l<b.l;
}
signed main()
{
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	register int i,j;
	cin>>n;
	for(i=1;i<=n;i++)
	{
		cin>>a[i].l>>a[i].r;
	}
	sort(a+1,a+n+1,cmp);//Sort by left range from large to small 
	start=a[1].l,end=a[1].r;
	for(i=2;i<=n;i++)
	{
		if(a[i].l<=end)//If the left end of the current interval is within the right end of the selected interval 
		{
			end=max(end,a[i].r);//Merging interval 
		}
		else//Instead, find a new area 
		{
			cout<<start<<' '<<end<<endl;
			start=a[i].l;//change 
			end=a[i].r;
		}
	}
	cout<<start<<' '<<end<<endl;//The last one must not be found, so it should be output once. 
	return 0;
}

And check the collection:

#include <stdio.h>
#include <iostream>
#include <algorithm>
using namespace std;
int f[100001],n,s;
typedef struct
{
	int l,r;
}lxydl;
lxydl a[50001];
inline bool cmp(lxydl a,lxydl b)
{
	return a.l<b.l;
}
int getfind(int v)//Look for ancestors. Father is the first interval number. 
{
	if(f[v]==v)
	{
		return v;
	}
	else
	{
		f[v]=getfind(f[v]);
		return f[v];
	}
}
inline void merge(int v,int u)//merge 
{
	register int t1,t2;
	t1=getfind(v);
	t2=getfind(u);
	if(t1!=t2)
	{
		f[t2]=t1;
	}
	if(a[u].r<a[v].r)
	{
		a[u].r=a[v].r;//Note that the two right sections should be the same 
	}
	return;
}
signed main()
{
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	register int i,j;
	cin>>n;
	for(i=1;i<=n;i++)
	{
		f[i]=i;//Preprocessing 
		cin>>a[i].l>>a[i].r;
	}
	sort(a+1,a+n+1,cmp);//Sort by left range from large to small 
	for(i=1;i<n;i++)
	{
		if(a[i+1].l<=a[i].r)//If the interval coincides 
		{
			merge(i,i+1);//Combine these two intervals 
		}
	}
	int cnt(-999999);
	for(i=1;i<=n;i++)
	{
		if(cnt!=f[i])//If a new interval is found 
		{
			cout<<a[i].l<<' ';
			cnt=f[i];
		}
		if(cnt!=f[i+1])//If the next interval doesn't coincide with it 
		{
			cout<<a[i].r<<endl;
		}
	}
	return 0;
}

 

Topics: iOS