zoukankan      html  css  js  c++  java
  • 【luoguP1382】楼房

    题目描述

    离散化,线段树维护区间修改,发现询问都是单点的\(max\),不妨把标记留在点上,不用下传,查询时取个\(max\)就可以了

    #include<algorithm>
    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<map>
    #define lc (p<<1)
    #define rc (p<<1|1)
    using namespace std;
    
    const int MAXN=400010;
    const int MAXM=1600010;
    
    inline int read(){
    	int x=0,f=1; char c=getchar();
    	while(c<'0'){ if(c=='-') f=-1; c=getchar(); }
    	while(c>='0') x=x*10+c-'0',c=getchar();
    	return x*f;
    }
    
    int n,x[MAXN],cnt,num;
    
    struct Data{
    	int l,r,h;
    } a[MAXN];
    
    map<int,int> Map;
    
    int tree[MAXM],rev[MAXN];
    
    inline void update(int L,int R,int h,int p=1,int l=1,int r=num){
    	if(L<=l&&r<=R){
    		tree[p]=max(tree[p],h);
    		return;
    	}
    	int mid=(l+r)>>1;
    	if(L<=mid) update(L,R,h,lc,l,mid);
    	if(R>mid) update(L,R,h,rc,mid+1,r);
    }
    
    inline int query(int x,int p=1,int l=1,int r=num){
    	if(l==r) return tree[p];
    	int mid=(l+r)>>1,ans=tree[p];
    	if(x<=mid) ans=max(ans,query(x,lc,l,mid));
    	else ans=max(ans,query(x,rc,mid+1,r));
    	return ans;
    }
    
    inline bool cmp(Data x,Data y){
    	if(x.l!=y.l)
    		return x.l<y.l;
    	return x.r<y.r;
    }
    
    int ansx[MAXN],ansy[MAXN],ansnum;
    
    int main(){
    	n=read();
    	for(int i=1;i<=n;++i)
    		a[i].h=read(),a[i].l=read(),a[i].r=read(),--a[i].r;
    	sort(a+1,a+1+n,cmp);
    	for(int i=1;i<=n;++i){
    		x[++cnt]=a[i].l;
    		x[++cnt]=a[i].l+1;
    		x[++cnt]=a[i].r;
    		x[++cnt]=a[i].r+1;
    	}
    	x[0]=x[1]-1;
    	sort(x+1,x+1+cnt);
    	for(int i=1;i<=cnt;++i)
    		if(x[i]!=x[i-1]) Map[x[i]]=++num,rev[num]=x[i];
    	++num;
    	for(int i=1;i<=n;++i)
    		update(Map[a[i].l],Map[a[i].r],a[i].h);
    	int last=0;
    	for(int i=1;i<=num;++i){
    		int tmp=query(i);
    		if(tmp!=last){
    			if(tmp>last){
    				ansx[++ansnum]=rev[i],ansy[ansnum]=last;
    				ansx[++ansnum]=rev[i],ansy[ansnum]=tmp;
    			}
    			else{
    				ansx[++ansnum]=rev[i-1]+1,ansy[ansnum]=last;
    				ansx[++ansnum]=rev[i-1]+1,ansy[ansnum]=tmp;
    			}
    			last=tmp;
    		}
    	}
    	printf("%d\n",ansnum);
    	for(int i=1;i<=ansnum;++i)
    		printf("%d %d\n",ansx[i],ansy[i]);
    	return 0;
    }
    
  • 相关阅读:
    关于量子计算机的一些整理 (精心整理原创) (1)
    自然语言交流系统 phxnet团队 创新实训 个人博客 (一)
    自然语言交流系统 phxnet团队 创新实训 项目博客 (一)
    double类型保留2位小数
    main函数位置
    java中main函数解析
    关于函数声明的小知识点
    数据帧、数据包、数据报以及数据段
    chrome 常用快捷键(可以摆脱鼠标哦)
    chrome 如何利用快捷键将光标移动到地址栏
  • 原文地址:https://www.cnblogs.com/66-CCF-F/p/11833949.html
Copyright © 2011-2022 走看看