这题意甚是难懂。。当且峰值为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 */