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

 

你可能感兴趣的:(uva)