1. 程式人生 > >CodeForces - 35E Parade (線段樹)

CodeForces - 35E Parade (線段樹)

題意:

給你幾個矩形,現在問你矩形輪廓線改變的座標在哪裡

思路:

怎樣的輪廓線會改變?其實就是當他們的高度改變的時候輪廓線會改變,那麼我們離散x座標,之後維護y的最大值,當y改變的時候我們就記錄下當前的橫座標,而縱座標剛好就是他的高度,其中有一個問題就是 當我們改[1,2]值為1區間和[3,4]值為2區間後 ,我們發現當我們查2的時候他的值是1,而查3的時候他的值是2,但是根據圖中畫的我們發現他的值其實應該是0才對,但是0剛好被我們所忽略掉了,怎麼辦呢?我們每次去修改的時候我們就修改他的[L,R-1]區間就好了,還有一個問題就是線段樹更新區間最大值的時候不需要用標記陣列啊 。。。。傻逼了找了一晚上bug。。。。

程式碼:

#include <bits/stdc++.h>
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
using namespace std;
const int maxn = 200000 + 10;
struct node
{
	int s,e,h;
}edg[maxn];
int Hash[maxn];
vector<pair<int,int> >V;
struct seg
{
	int tree[maxn<<2];
	void pushdown(int rt)
	{
		if(!tree[rt]) return ;
		tree[rt<<1] = max(tree[rt<<1] , tree[rt]);
		tree[rt<<1|1] = max(tree[rt<<1|1] , tree[rt]);
		tree[rt] = 0;
	}
	void build(int l,int r,int rt)
	{
		tree[rt] = 0 ;
		if(l == r) return ;
		int m = (l+r)>>1;
		build(lson);
		build(rson);
	}
	void update(int L,int R,int val,int l,int r,int rt)
	{
		//printf("%d %d %d %d\n",L,R,l,r);
		if(l >= L && r <= R)
		{
			tree[rt] = max(tree[rt] , val);
			return ;
		}
		pushdown(rt);
		int m = (l+r)>>1;
		if(m >= L) update(L,R,val,lson);
		if(m < R) update(L,R,val,rson);
	}
	void print(int l,int r,int rt)
	{
		if(l == r) {printf("L = %d  R = %d  V = %d \n",l,r,tree[rt]); return ;}
		int m = (l+r)>>1;
		print(lson);
		print(rson);
	}
	int query(int pos,int l,int r,int rt)
	{
		if(l == r) return tree[rt];
		pushdown(rt);
		int m = (l+r)>>1;
		if(m >= pos) return query(pos,lson);
		else return query(pos,rson);
	}
}tree;
int main()
{
//	freopen("input.txt","r",stdin);
//    freopen("output.txt","w",stdout);
	int n;
	scanf("%d",&n);
	int cnt = 0;
	for(int i = 0 ; i < n ; i++)
	{
		scanf("%d%d%d",&edg[i].h,&edg[i].s,&edg[i].e);
		Hash[cnt++] = edg[i].s;
		Hash[cnt++] = edg[i].e; 
	}
	sort(Hash,Hash+cnt);
	cnt = unique(Hash,Hash+cnt) - Hash;
	tree.build(1,cnt,1);
	for(int i = 0 ; i < n ; i++)
	{
		int L = lower_bound(Hash,Hash+cnt,edg[i].s) - Hash + 1;
		int R = lower_bound(Hash,Hash+cnt,edg[i].e) - Hash;
		int p = edg[i].h;
		tree.update(L,R,p,1,cnt,1);
	}
	int now = 0 , last = 0;
	for(int i = 0 ; i < cnt - 1; i++)
	{
		int pos = i+1;
		now = tree.query(pos,1,cnt,1);
		if(now != last)
		{	
			V.push_back(make_pair(Hash[i],last));
			V.push_back(make_pair(Hash[i],now));
		}
		last = now;
	}
	if(now != 0)
	{
		V.push_back(make_pair(Hash[cnt-1],last));
		V.push_back(make_pair(Hash[cnt-1],0));
	}
	cout<<V.size()<<endl;
	for(int i = 0 ; i < V.size() ; i ++) cout<<V[i].first<<" "<<V[i].second<<endl;
}