这题意甚是难懂。。当且峰值为h 如果他能为ultras 需要满足条件 d>=15W d满足它到任意一个比它高的点须经过h-d这个点
通俗一点来说,如果这个点满足条件 就找离他最近的一个<=h-15W的点 看他们之间是否有比它更高的点 如果没有的话 它就满足条件
需要左右两边找。
用线段树依次插入点值 位置为节点值 更新最大值及最小值。
需要离散化 卡时间。。
1 #include <iostream>
2 #include<cstdio>
3 #include<cstring>
4 #include<algorithm>
5 #include<stdlib.h>
6 #include<cmath>
7 using namespace std;
8 #define N 1000010
9 #define M 100010
10 int s[N<<2],ss[N<<2];
11 int h[M],o[M],n,p[N],hi[M<<1];
12 bool f[M],ff[N];
13 void update(int oo,int p,int d,int l,int r,int w)
14 {
15 if(l==r)
16 {
17 if(oo)
18 s[w] = d;
19 else
20 ss[w] = d;
21 return ;
22 }
23 int m = (l+r)>>1;
24 if(p<=m)
25 update(oo,p,d,l,m,w<<1);
26 else
27 update(oo,p,d,m+1,r,w<<1|1);
28 if(oo)
29 s[w] = max(s[w<<1],s[w<<1|1]);
30 else
31 ss[w] = min(ss[w<<1],ss[w<<1|1]);
32 }
33 int query(int oo,int a,int b,int l,int r,int w)
34 {
35 if(a<=l&&b>=r)
36 {
37 if(oo)
38 return s[w];
39 else
40 return ss[w];
41 }
42 int m = (l+r)>>1,re;
43 if(oo)
44 {
45 re = 0;
46 if(a<=m)
47 re = query(oo,a,b,l,m,w<<1);
48 if(b>m)
49 re = max(re,query(oo,a,b,m+1,r,w<<1|1));
50 }
51 else
52 {
53 re = n+1;
54 if(a<=m)
55 re = query(oo,a,b,l,m,w<<1);
56 if(b>m)
57 re = min(re,query(oo,a,b,m+1,r,w<<1|1));
58 }
59 return re;
60 }
61 void build(int l,int r,int w,int oo)
62 {
63 if(l==r)
64 {
65
66 if(oo)
67 s[w] = 0;
68 else
69 ss[w] = n+1;
70 return ;
71 }
72 int m = (l+r)>>1;
73 build(l,m,w<<1,oo);
74 build(m+1,r,w<<1|1,oo);
75 if(oo)
76 s[w] = max(s[w<<1],s[w<<1|1]);
77 else
78 ss[w] = min(ss[w<<1],ss[w<<1|1]);
79 }
80 int main()
81 {
82 int i;
83 int hh = 150000,num=0;
84 while(scanf("%d",&n)!=EOF)
85 {
86 memset(f,0,sizeof(f));
87 memset(ff,0,sizeof(ff));
88 int mm = 0,e = 0;
89 for(i = 1; i <= n ;i++)
90 {
91 scanf("%d",&h[i]);
92 if(!ff[h[i]])
93 {
94 hi[e++] = h[i];
95 ff[h[i]] = 1;
96 }
97 if(h[i]>hh)
98 {
99 if(!ff[h[i]-hh])
100 hi[e++] = h[i]-hh;
101 ff[h[i]-hh] = 1;
102 }
103 }
104 sort(hi,hi+e);
105 int ko = 0;
106 for(i = 0;i < e; i++)
107 {
108 p[hi[i]] = ++ko;
109 }
110 mm = ko+1;
111 build(1,mm,1,1);
112 update(1,1,1,1,mm,1);
113 for(i = 2; i < n ;i++)
114 {
115 if(h[i]<=hh)
116 {
117 update(1,p[h[i]],i,1,mm,1);
118 continue;
119 }
120 if(h[i]>=h[i-1]&&h[i]>=h[i+1])
121 {
122 f[i] = 1;
123 int k1 = query(1,1,p[h[i]-hh],1,mm,1);
124 int k2 = query(1,p[h[i]]+1,mm,1,mm,1);
125 if(k2)
126 {
127 if(!k1||k2>k1)
128 f[i] = 0;
129 }
130 }
131 update(1,p[h[i]],i,1,mm,1);
132 }
133 build(1,mm,1,0);
134 update(0,1,n,1,mm,1);
135 for(i = n-1; i >= 2 ; i--)
136 {
137 if(f[i])
138 {
139 int k1 = query(0,1,p[h[i]-hh],1,mm,1);
140 int k2 = query(0,p[h[i]]+1,mm,1,mm,1);
141 if(k2!=n+1)
142 {
143 if(k1==n+1||k2<k1)
144 f[i] = 0;
145 }
146 }
147 update(0,p[h[i]],i,1,mm,1);
148 }
149 int g = 0;
150 for(i = 1; i <= n; i++)
151 if(f[i])
152 o[++g] = i;
153 for(i = 1 ; i < g; i++)
154 printf("%d ",o[i]);
155 printf("%d\n",o[i]);
156 }
157 return 0;
158 }
159 /*
160 26
161 0 50000 150000 200000 150000
162 200000 300000 100000 50000 150000 330000 350000
163 250000 350000 200000 220000 300000 50000 100000
164 250000 100000 150000 500000 300000 250000 0
165 */
UVA6531Go up the ultras,布布扣,bubuko.com
时间: 2024-09-30 15:51:36