链接

这题意甚是难懂。。当且峰值为h 如果他能为ultras 需要满足条件 d>=15W d满足它到任意一个比它高的点须经过h-d这个点

通俗一点来说,如果这个点满足条件 就找离他最近的一个<=h-15W的点 看他们之间是否有比它更高的点  如果没有的话 它就满足条件 需要左右两边找。

用线段树依次插入点值  位置为节点值 更新最大值及最小值。

需要离散化 卡时间。。

 #include <iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<stdlib.h>
#include<cmath>
using namespace std;
#define N 1000010
#define M 100010
int s[N<<],ss[N<<];
int h[M],o[M],n,p[N],hi[M<<];
bool f[M],ff[N];
void update(int oo,int p,int d,int l,int r,int w)
{
if(l==r)
{
if(oo)
s[w] = d;
else
ss[w] = d;
return ;
}
int m = (l+r)>>;
if(p<=m)
update(oo,p,d,l,m,w<<);
else
update(oo,p,d,m+,r,w<<|);
if(oo)
s[w] = max(s[w<<],s[w<<|]);
else
ss[w] = min(ss[w<<],ss[w<<|]);
}
int query(int oo,int a,int b,int l,int r,int w)
{
if(a<=l&&b>=r)
{
if(oo)
return s[w];
else
return ss[w];
}
int m = (l+r)>>,re;
if(oo)
{
re = ;
if(a<=m)
re = query(oo,a,b,l,m,w<<);
if(b>m)
re = max(re,query(oo,a,b,m+,r,w<<|));
}
else
{
re = n+;
if(a<=m)
re = query(oo,a,b,l,m,w<<);
if(b>m)
re = min(re,query(oo,a,b,m+,r,w<<|));
}
return re;
}
void build(int l,int r,int w,int oo)
{
if(l==r)
{ if(oo)
s[w] = ;
else
ss[w] = n+;
return ;
}
int m = (l+r)>>;
build(l,m,w<<,oo);
build(m+,r,w<<|,oo);
if(oo)
s[w] = max(s[w<<],s[w<<|]);
else
ss[w] = min(ss[w<<],ss[w<<|]);
}
int main()
{
int i;
int hh = ,num=;
while(scanf("%d",&n)!=EOF)
{
memset(f,,sizeof(f));
memset(ff,,sizeof(ff));
int mm = ,e = ;
for(i = ; i <= n ;i++)
{
scanf("%d",&h[i]);
if(!ff[h[i]])
{
hi[e++] = h[i];
ff[h[i]] = ;
}
if(h[i]>hh)
{
if(!ff[h[i]-hh])
hi[e++] = h[i]-hh;
ff[h[i]-hh] = ;
}
}
sort(hi,hi+e);
int ko = ;
for(i = ;i < e; i++)
{
p[hi[i]] = ++ko;
}
mm = ko+;
build(,mm,,);
update(,,,,mm,);
for(i = ; i < n ;i++)
{
if(h[i]<=hh)
{
update(,p[h[i]],i,,mm,);
continue;
}
if(h[i]>=h[i-]&&h[i]>=h[i+])
{
f[i] = ;
int k1 = query(,,p[h[i]-hh],,mm,);
int k2 = query(,p[h[i]]+,mm,,mm,);
if(k2)
{
if(!k1||k2>k1)
f[i] = ;
}
}
update(,p[h[i]],i,,mm,);
}
build(,mm,,);
update(,,n,,mm,);
for(i = n-; i >= ; i--)
{
if(f[i])
{
int k1 = query(,,p[h[i]-hh],,mm,);
int k2 = query(,p[h[i]]+,mm,,mm,);
if(k2!=n+)
{
if(k1==n+||k2<k1)
f[i] = ;
}
}
update(,p[h[i]],i,,mm,);
}
int g = ;
for(i = ; i <= n; i++)
if(f[i])
o[++g] = i;
for(i = ; i < g; i++)
printf("%d ",o[i]);
printf("%d\n",o[i]);
}
return ;
}
/*
26
0 50000 150000 200000 150000
200000 300000 100000 50000 150000 330000 350000
250000 350000 200000 220000 300000 50000 100000
250000 100000 150000 500000 300000 250000 0
*/

最新文章

  1. Linux系统资源查看
  2. 黑马程序员——C语言基础 函数
  3. C# 委托和事件(二):使用.Net框架中的EventArgs和EventHandler
  4. ng-repeat指令使用详解
  5. [译]Probable C# 6.0 features illustrated
  6. android 跳转到系统设置界面的所有Intent
  7. tnsnames.ora存放路径
  8. Android 核心分析 之六 IPC框架分析 Binder,Service,Service manager
  9. 【Hadoop学习】Super用户以其他用户的名义执行操作
  10. Limit参数优化MySQL查询的方法
  11. C#学习笔记7:多态是面向对象的三大特征(封装、继承、多态)之一
  12. nyoj 119 士兵杀敌(三)【线段树区间最大值最小值差】
  13. 移动端与PHP服务端接口通信流程设计(增强版)
  14. IIS充当代理转发请求到Kestrel
  15. Loadrunner11不能调用IE8解决方法大全
  16. 即将发布的 ASP.NET Core 2.2 会有哪些新玩意儿?
  17. java开发师笔试面试每日12题(1)
  18. PCA(主成分分析)的简单理解
  19. 潭州课堂25班:Ph201805201 并发(协程) 第十五课 (课堂笔记)
  20. SPRING的事务配置详解

热门文章

  1. luogu3373 【模板】线段树2
  2. iOS 获取WIFI SSID及MAC地址
  3. spring核心框架体系结构(各个jar包作用)
  4. YTU 2203: 最小节点(线性表)
  5. ubuntu 源、codename 与 sources.list 文件
  6. 获取指定类型如枚举/属性上自定义attribue值
  7. Servlet分页查询
  8. 【前端】CentOS 7 系列教程之二: 安装 git 最新版
  9. .NETFramework:HttpRuntime
  10. ASP.NET Core:创建一个Core项目