其他分享
首页 > 其他分享> > [火星补锅] 水题大战Vol.2 T1 && luogu P1904 天际线 题解 (线段树)

[火星补锅] 水题大战Vol.2 T1 && luogu P1904 天际线 题解 (线段树)

作者:互联网

前言:

当时考场上并没有想出来。。。后来也是看了题解才明白

解析:

大家(除了我)都知道,奇点和偶点会成对出现,而出现的前提就是建筑的高度突然发生变化。

to be continued ...

代码:

#include <bits/stdc++.h>
using namespace std;
const int maxn=100000+10;
#define gc() (p1 == p2 ? (p2 = buf + fread(p1 = buf, 1, 1 << 20, stdin), p1 == p2 ? EOF : *p1++) : *p1++)
#define read() ({ register int x = 0, f = 1; register char c = gc(); while(c < '0' || c > '9') { if (c == '-') f = -1; c = gc();} while(c >= '0' && c <= '9') x = x * 10 + (c & 15), c = gc(); f * x; })
char buf[1 << 20], *p1, *p2;
struct node{
	int xx,yy,zz;
}b[maxn];
int tot,Max;
struct Segment_tree{
	int val,lazy;
}tree[maxn<<2];
void pushup(int rt){
	tree[rt].val=max(tree[rt<<1].val,tree[rt<<1|1].val);
}
void update(int rt,int w){
	if(tree[rt].val<w) tree[rt].val=w;
	if(tree[rt].lazy<w) tree[rt].lazy=w;
}
void pushdown(int rt){
	if(tree[rt].lazy){
		update(rt<<1,tree[rt].lazy);
		update(rt<<1|1,tree[rt].lazy);
		tree[rt].lazy=0;
	}
}
void modify(int rt,int l,int r,int s,int t,int w){
	if(s<=l&&r<=t){
		update(rt,w);
		return;
	}
	int mid=(l+r)>>1;
	pushdown(rt);
	if(s<=mid) modify(rt<<1,l,mid,s,t,w);
	if(t>mid) modify(rt<<1|1,mid+1,r,s,t,w);
	pushup(rt);
}
int query(int rt,int l,int r,int x){
	if(l==r) return tree[rt].val;
	int mid=(l+r)>>1;
	pushdown(rt);
	if(x<=mid) return query(rt<<1,l,mid,x);
	else return query(rt<<1|1,mid+1,r,x);
}
void Solve(){
	int x,y,z;
	while(scanf("%d%d%d",&x,&z,&y)!=EOF){
		tot++;
		b[tot].xx=x;
		b[tot].yy=y;
		b[tot].zz=z;
		Max=max(Max,y);
	}
	for(int i=1;i<=tot;++i) modify(1,1,Max,b[i].xx,b[i].yy-1,b[i].zz);
	for(int i=1,H=0;i<=Max;++i){
		int h=query(1,1,Max,i);
		if(H!=h){
			H=h;
			printf("%d %d\n",i,h);
		}
	}
}
int main(){
	Solve();
	return 0;
}

标签:rt,天际线,补锅,题解,gc,&&,pushdown,buf
来源: https://www.cnblogs.com/wwcdcpyscc/p/13905079.html