zoukankan      html  css  js  c++  java
  • [火星补锅] 水题大战Vol.2 T1 && luogu P1904 天际线 题解 (线段树)

    前言:

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

    解析:

    大家(除了我)都知道,奇点和偶点会成对出现,而出现的前提就是建筑的高度突然发生变化。(这个性质挺重要的,我之前没看出来)
    所以就可以扫一遍,然后就搞定了。
    然后还有一个小点,要把每个区间搞成左闭右开,否则碰到诸如 (3,7,5)和(5,8,9) 这样的数据,中间的空隙就不会被计算。
    然后写个线段树维护一下就ok了

    代码
    #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
    ",i,h);
    		}
    	}
    }
    int main(){
    	Solve();
    	return 0;
    }
    
    
  • 相关阅读:
    Linux Select之坑
    BitCoin p2p通信过程
    2018软工实践——团队答辩
    Ubuntu16安装GTK+2.0教程
    福大软工1816 · 第五次作业
    福大软工1816 · 第五次作业
    福大软工1816 · 第五次作业
    福大软工1816 · 第五次作业
    Notepad++一键编译运行(Python、Java、C++)
    福大软工1816 · 第四次作业
  • 原文地址:https://www.cnblogs.com/wwcdcpyscc/p/13905079.html
Copyright © 2011-2022 走看看