UVA6531Go up the ultras

链接

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

 

posted @ 2014-05-02 19:21  _雨  阅读(332)  评论(10编辑  收藏  举报