题意:
给你几个矩形,现在问你矩形轮廓线改变的坐标在哪里
思路:
怎样的轮廓线会改变?其实就是当他们的高度改变的时候轮廓线会改变,那么我们离散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;
}