线段树维护最值+离散化 50分求助
查看原帖
线段树维护最值+离散化 50分求助
494210
Sevendays_Coder楼主2022/8/24 21:37

#5、6、7、9RE

#10 WA

调了好久都没改进——蒟蒻无奈

#include<bits/stdc++.h>
const int N=4e5+5;
#define lc (k<<1)
#define rc ((k<<1)|1)
#define mid ((l+r)>>1)
using namespace std;
inline int Read()
{
	int x=0,f=1;
	char ch=getchar();
	while(!isdigit(ch))
	{
		if(ch=='-')
			f=-1;
		ch=getchar();
	}
	while(isdigit(ch))
	{
		x=(x<<1)+(x<<3)+ch-'0';
		ch=getchar();
	}
	return x*f;
}
struct Node
{
	int l,r,h;
}P[N<<2];
struct Segment_Tree
{
	int Maxn[N<<2];	
	void Pushdown(int k)
	{
		Maxn[lc]=max(Maxn[lc],Maxn[k]);
		Maxn[rc]=max(Maxn[rc],Maxn[k]);
	}
	void Update(int k,int l,int r,int x,int y,int z)
	{
		//cout<<k<<' '<<l<<' '<<r<<' '<<x<<' '<<y<<' '<<z<<endl;
		if(x<=l&&r<=y)
		{
			Maxn[k]=max(Maxn[k],z);
		//	cout<<'U'<<l<<' '<<r<<' '<<Maxn[k]<<endl;
			return;
		}
		Pushdown(k);
		if(x<=mid)
			Update(lc,l,mid,x,y,z);
		if(y>mid)
			Update(rc,mid+1,r,x,y,z);
	}
	int Query(int k,int l,int r,int x)
	{
		//cout<<k<<' '<<l<<' '<<r<<' '<<x<<endl;
		if(l==r)
			return Maxn[k];
		Pushdown(k);
		if(x<=mid)
			return Query(lc,l,mid,x);
		else
			return Query(rc,mid+1,r,x);
	}
}St;
vector<int>V;
vector<pair<int,int> >Ans;
int main()
{
	int n=Read();
	for(int i=1;i<=n;i++)
	{
		P[i].h=Read(),P[i].l=Read(),P[i].r=Read();
		V.push_back(P[i].l),V.push_back(P[i].r); 
	}
	sort(V.begin(),V.end());
	int m=unique(V.begin(),V.end())-V.begin();
	for(int i=1;i<=n;i++)
	{
		P[i].l=lower_bound(V.begin(),V.end(),P[i].l)-V.begin()+1;
		P[i].r=lower_bound(V.begin(),V.end(),P[i].r)-V.begin()+1;//离散化 
		St.Update(1,1,m,P[i].l,P[i].r-1,P[i].h); //区间修改 
	}
	int tmp=0;
	Ans.push_back(make_pair(V[0],0)); 
	for(int i=1;i<m;i++) 
	{
		int h=St.Query(1,1,m,i);//该点高度 
		if(h==tmp)//一马平川(这个点并没有使高度改变 ) 
			Ans[Ans.size()-1].first=V[i];//推进(该高度的右端赋为下一点) 
		else//波澜起伏(该点为转折点——注意此时以记录该点(上个高度的) 
		{
			Ans.push_back(make_pair(V[i-1],h));//找这个坐标当前高度的转折点 
			Ans.push_back(make_pair(V[i],h));//先标记当前高度的下一个点,慢慢标记右端点 
		}
		tmp=h;//别忘了更新“上个高度” 
	}
	Ans.push_back(make_pair(V[m-1],0));
	printf("%d\n",Ans.size());
	for(int i=0;i<Ans.size();i++)
		printf("%d %d\n",Ans[i].first,Ans[i].second);
 	return 0;
}
2022/8/24 21:37
加载中...