链接:https://ac.nowcoder.com/acm/contest/7412/E
来源:牛客网

题目描述
牛牛最喜欢爬山了,他喜欢站在最高的山峰上展望。
牛牛来到山脚下,看到这里一共有 n 个山峰,每个山峰有一个坐标 xix_ixi​和高度 hih_ihi​(n个山峰在一条直线上),参差不齐,心里瞬间很不舒服。他最喜欢看到的山峰是从左到右高度依次增大,所以牛牛就要使用魔法了。当牛牛登上第 i 个山峰的时候,他要用乾坤大挪移把当前山峰左边(xj<xi)(x_j<x_i)(xj​<xi​)第一个比这个山峰严格大的山峰变得和当前山峰一样高,如果右边(xj>xi)(x_j>x_i)(xj​>xi​)没有山峰比他严格大,牛牛还是很不满足,他要把右边最小的山峰变成和当前山峰一样大(如果有多个最小的,变最左边的一个),当牛牛从第 n 个山峰下来的时候,看到这一场面,心中很是满足,但是他不知道自己把山峰都变成什么样了,想要知道每个山峰的新高度 hih_ihi​ ,你能告诉他吗?
注意:登山顺序不一定从左到右,是按照给出山峰的顺序

输入描述:
第一行有一个正整数n(n≤2×105)n(n \leq 2×10^5)n(n≤2×105),表示有 n 座山峰
接下来 n 行每行有两个整数x ,h(10−9≤x≤109,1≤h≤109)h(10^{-9} \leq x\leq 10^9,1\leq h\leq 10^9)h(10−9≤x≤109,1≤h≤109)(保证每个 x 都不相同)

输出描述:
输出一行,n 个数,分别表示第 i 个山峰最后的高度 h

思路:线段树区间查询、单点修改,注意:结果要按照输入的顺序输出。

1、查询区间第一个大于val的数的位置:

int query_max(int root,int l,int r,int ll,int rr,int val)
//ll~rr中比val大的第一个数的位置
{if(tree[root].mmax<=val)return 0;if(l==r){return l;}int pos=0;if(rr<=mid)pos=query_max(chl,l,mid,ll,rr,val);else if(ll>mid)pos=query_max(chr,mid+1,r,ll,rr,val);else{pos=query_max(chr,mid+1,r,mid+1,rr,val);if(!pos)pos=query_max(chl,l,mid,ll,mid,val);}return pos;
}

2、查询区间最小值及其位置

PII query_min(int root,int l,int r,int ll,int rr)
//ll~rr中最小值的位置
{if(l==ll&&r==rr){return make_pair(tree[root].mmin,tree[root].pos);}if(rr<=mid)return query_min(chl,l,mid,ll,rr);else if(ll>mid)return query_min(chr,mid+1,r,ll,rr);else return min(query_min(chl,l,mid,ll,mid),query_min(chr,mid+1,r,mid+1,rr));
}

代码:

#include<algorithm>
#include<iostream>
#include<cstdio>
#include<cstring>
#include<map>
#include<set>
#include<string>
#include<queue>
using namespace std;
#define LL long long
#define uLL unsigned long long
#define PII pair<int,int>
#define mid ((l + r)>>1)
#define chl (root<<1)
#define chr (root<<1|1)
const int manx = 2e5 + 10;
const int INF = 0x3fffffff;
const int mod = 1e4+7;int n,x,h;
int num[manx],lis[manx],a[manx],b[manx],tmp[manx];
struct node
{int mmax;int mmin,pos;
}tree[manx<<2];
void eval(int root)
{tree[root].mmax=max(tree[chl].mmax,tree[chr].mmax);tree[root].mmin=min(tree[chl].mmin,tree[chr].mmin);tree[root].pos=tree[chl].mmin<=tree[chr].mmin?tree[chl].pos:tree[chr].pos;
}
void build_tree(int root,int l,int r)
{if(l==r){tree[root].pos=l;tree[root].mmax=tree[root].mmin=num[l];return;}build_tree(chl,l,mid);build_tree(chr,mid+1,r);eval(root);
}
void change(int root,int l,int r,int pos,int val)
{if(l==r){num[l]=tree[root].mmax=tree[root].mmin=val;return;}if(pos<=mid)change(chl,l,mid,pos,val);else change(chr,mid+1,r,pos,val);eval(root);
}
int query_max(int root,int l,int r,int ll,int rr,int val)//ll~rr中比val大的第一个数的位置
{if(tree[root].mmax<=val)return 0;if(l==r){return l;}int pos=0;if(rr<=mid)pos=query_max(chl,l,mid,ll,rr,val);else if(ll>mid)pos=query_max(chr,mid+1,r,ll,rr,val);else{pos=query_max(chr,mid+1,r,mid+1,rr,val);if(!pos)pos=query_max(chl,l,mid,ll,mid,val);}return pos;
}
PII query_min(int root,int l,int r,int ll,int rr)//ll~rr中最小值的位置
{if(l==ll&&r==rr){return make_pair(tree[root].mmin,tree[root].pos);}if(rr<=mid)return query_min(chl,l,mid,ll,rr);else if(ll>mid)return query_min(chr,mid+1,r,ll,rr);else return min(query_min(chl,l,mid,ll,mid),query_min(chr,mid+1,r,mid+1,rr));
}
int main()
{scanf("%d",&n);for(int i=1;i<=n;i++){scanf("%d",&a[i]);tmp[i]=a[i];scanf("%d",&b[i]);}sort(tmp+1,tmp+n+1);for(int i=1;i<=n;i++){int pos=lower_bound(tmp+1,tmp+n+1,a[i])-tmp;lis[i]=pos;num[pos]=b[i];}build_tree(1,1,n);for(int i=1;i<=n;i++){int val=num[lis[i]];int pos;if(lis[i]>1&&(pos=query_max(1,1,n,1,lis[i]-1,val)))change(1,1,n,pos,val);if(lis[i]<n&&(!query_max(1,1,n,lis[i]+1,n,val))){PII ans=query_min(1,1,n,lis[i]+1,n);pos=ans.second;change(1,1,n,pos,val);}}for(int i=1;i<=n;i++)printf("%d%c",num[lis[i]],i==n?'\n':' ');return 0;
}

牛客小白月赛28—E会当凌绝顶,一览众山小(线段树)相关推荐

  1. 牛客小白月赛28 E-会当凌绝顶,一览众山小 线段树+二分暴力模拟

    牛客小白月赛28 E-会当凌绝顶,一览众山小 线段树+二分暴力模拟 题意 思路 Code 传送门: https://ac.nowcoder.com/acm/contest/16081/E 题意 登山顺 ...

  2. 牛客小白月赛28 J.树上行走

    牛客小白月赛28 J.树上行走 题目链接 题目描述 牛牛苦练武功绝学--轻功水上漂,最终没有练成,但是他学会了在树上行走的本领. 这天,牛牛落入了敌人的陷阱,身后有巨石追击,面前有n个点,n-1条边连 ...

  3. 牛客小白月赛28 D.位运算之谜

    牛客小白月赛28 D.位运算之谜 题目链接 题目描述 a+ba + ba+b 的值为 xxx,a&ba\&ba&b 的值为 yyy,首先需要判断能否有一组 a,ba,ba,b ...

  4. 牛客小白月赛28 B.牛牛和牛可乐的赌约2

    牛客小白月赛28 B.牛牛和牛可乐的赌约2 题目链接 题目描述 牛牛感觉在上一次赌约中,情况对于自己非常不利,所以决定再赌一场. 这时候,牛蜓队长出现了:第一,绝对不意气用事:第二,绝对不漏判任何一件 ...

  5. 牛客小白月赛28 G.牛牛和字符串的日常

    牛客小白月赛28 G.牛牛和字符串的日常 题目链接 题目描述 牛牛每天都要做的事就是读书,从书里找自己喜欢的句子,他每天都会去读一本书,如果牛牛今天读的书的某连续 k k k 个字符刚好是牛牛喜欢句子 ...

  6. 牛客小白月赛28 A牛牛和牛可乐的赌约 (数论-费马小定理)

    题目 A牛牛和牛可乐的赌约 题目链接 传送门 题解 注意阅读题目是计算牛牛输的概率. 需要掌握的知识点 快速幂 费马小定理 分数取模 首先我们容易知道 牛牛 赢的概率是 1 n m \frac{1}{ ...

  7. 牛客小白月赛28 C-单词记忆方法——dfs

    单词记忆方法 题目描述 牛牛考完了四六级,准备分享一下自己的英语学习方法. 牛牛:学习英语最重要的就是背单词,如果你能把所有的单词都记住,那么你的英语就能变成天下第一. 然而牛牛的记忆方法就是把单词的 ...

  8. 牛客小白月赛6 J.洋灰三角

    牛客小白月赛6 J.洋灰三角 题目链接 题目描述 洋灰是一种建筑材料,常用来筑桥搭建高层建筑,又称,水泥.混凝土. WHZ有很多铸造成三角形的洋灰块,他想把这些洋灰三角按照一定的规律放到摆成一排的n个 ...

  9. 牛客小白月赛16 小石的签到题(博弈)

    牛客小白月赛16 小石的签到题 链接:https://ac.nowcoder.com/acm/contest/949/A来源:牛客网 题目描述 输入描述: 共一行,输入一个数 nnn . 输出描述: ...

最新文章

  1. miniz库简介及使用
  2. linux 挂载光盘映像,在 Windows Mac和Linux上,如何挂载iso和其他光盘映像
  3. java中怎么使用json数据_JAVA中使用JSON进行数据传递
  4. 虚拟机网络连接三种方式(桥接、NAT、主机)
  5. C#LeetCode刷题之#643-子数组最大平均数 I( Maximum Average Subarray I)
  6. Spring项目在启动时报Error running 'ProviderC': Cannot start process, the working directory 'E:\ ' does not
  7. 微信表情包储服务器,微信新功能!不用存图就能发出海量表情包
  8. php trait编译实现,为什么PHP Trait不能实现接口?
  9. NetScaler Active-Active模式
  10. 模板题——质数、素数、约数
  11. css通过行内样式绑定背景图片
  12. 游戏外挂:用Python做个小游戏的开挂
  13. 嵌入式工程师面试题集-MCU_STM32
  14. 2021河南科技大学计算机考研科目,2021河南科技大学考研参考书目
  15. 计算机程序设计在日常生活中的应用,《走进程序设计》教学设计
  16. Android 获取设备唯一标识
  17. 国外变电站3d可视化技术发展_国外沥青路面纵向施工接缝技术的发展
  18. AGV与电梯交互系统设计
  19. 洛谷P2598 狼和羊的故事
  20. 内网穿透-利用frp进行远程桌面控制(window服务端,window客户端)

热门文章

  1. lob 索引 oracle,解决了困惑已久的Oracle全文索引问题
  2. 使用接口实现手机功能------完善
  3. cocos2d-x 3.0 制作横版格斗游戏
  4. TortoiseGit小乌龟工具上传解析
  5. php一年过去多少天,php 显示今天是星期几与一年的每几天代码
  6. magicalcoder集成布局器
  7. Spring Boot 实现 AI 人脸识别功能,So Easy!
  8. 关于男人和女人的一些想法
  9. 【20保研】兰州大学信息科学与工程学院2019年优秀大学生暑期夏令营活动通知...
  10. [多校 NOIP 联合模拟 11.30 T4] ZZH 的旅行(李超树合并) | 错题本