守卫

一道大难题

原著

好处理的是0区间,把他们删掉,然后重标号。对于0区间在\(L\)数组中把它并到右边,在\(R\)数组中把它并到左边。这样的作用是对于1区间,如果它其中包含部分0区间,就可以去掉这些0区间。(说不太清楚,手推一下样例)
然后对剩下的1区间处理一下(重标号了嘛),排序,去掉包含了小区间的大区间(它没用)。然后借助贪心。。。。
看代码吧(好像也不是特别理解)

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define mid ((l+r)>>1)
using namespace std;
const int N = 100005;
struct node{
	int l,r,f;
	bool operator < (const node &cc){
		return l<cc.l;
	}
}a[N];
int b[N],L[N],R[N],be[N],F[N],G[N];
int read()
{
	char c=getchar();
	int ans=0,w=1;
	while((c>'9'||c<'0')&&c!='-') c=getchar();
	if(c=='-') { w=-1; c=getchar(); }
	while(c>='0'&&c<='9')
	{ ans=ans*10+c-'0'; c=getchar(); }
	return ans*w;
}
//bool cmp(node x,node y)
//{ return x.l<y.l;}
int main()
{
	int n=read(),k=read(),m=read();
	for(int i=1;i<=m;i++)
	{
		a[i].l=read(); a[i].r=read(); a[i].f=read();
		if(a[i].f==0) ++b[a[i].l],--b[a[i].r+1];
	}
	int cur=0,cnt=0;
	for(int i=1;i<=n;i++)
	{
		cur+=b[i];
		if(cur==0) L[i]=R[i]=++cnt,be[cnt]=i;
	}
	if(cnt==k)
	{
		for(int i=1;i<=cnt;i++)
		 printf("%d\n",be[i]);
		return 0;
	}
	L[n+1]=n+1;
	for(int i=1;i<=n;i++)
	 if(R[i]==0) R[i]=R[i-1];
	for(int i=n;i>=1;--i)
	 if(L[i]==0) L[i]=L[i+1];
	cnt=0;
	for(int i=1;i<=m;i++)
	{
		if(a[i].f==0) continue;
		int l=L[a[i].l],r=R[a[i].r];
		if(l<=r) a[++cnt].l=l,a[cnt].r=r;
	}
	sort(a+1,a+cnt+1);
	int top=0;
	for(int i=1;i<=cnt;i++)
	{
		while(top&&a[i].l>=L[top]&&a[i].r<=R[top]) --top;
		L[++top]=a[i].l,R[top]=a[i].r;
	}
	int l=n+1,r=0;
	for(int i=1;i<=top;i++)
	{
		if(L[i]>r) F[i]=F[i-1]+1,r=R[i];
		else F[i]=F[i-1];
	}
	for(int i=top;i>=1;i--)
	{
		if(R[i]<l) G[i]=G[i+1]+1,l=L[i];
		else G[i]=G[i+1];
	}
	bool ok=0;
	for(int i=1;i<=top;i++)
	{
		if(F[i]==F[i-1]) continue;
		if(L[i]==R[i]) 
		{
			printf("%d\n",be[R[i]]);
			ok=1; continue;
		}
		int l=1,r=i-1,x=0,y=top+1;
		while(l<=r)
		{
			if(R[mid]<R[i]-1) x=mid,l=mid+1;
			else r=mid-1;
		}
		l=i+1,r=top;
		while(l<=r)
		{
			if(L[mid]>R[i]-1) y=mid,r=mid-1;
			else l=mid+1;
		}
		if(F[x]+G[y]+1>k) 
		{
			printf("%d\n",be[R[i]]);
			ok=1;
		}
	}
	if(!ok) puts("-1");
	return 0;
}
posted @ 2019-08-07 20:03  蟹蟹王  阅读(176)  评论(0编辑  收藏  举报