标签:for eof 维护 star odi uil images UI codility
http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1272
第1行:1个数N,表示数组的长度(2 <= N <= 50000)。 第2 - N + 1行:每行1个数,对应数组元素Ai(1 <= Ai <= 10^9)。
输出最大距离。
6 5 3 6 3 4 2
3
一个很明显的做法是线段树维护区间最大值,然后二分查找最右的点。
我们还可以将这些数标记坐标之后按照值得大小升序排列,价值相同的坐标小的优先。
排序之后,每个数的最优点一定位于这个数的右侧,换句话说将求解的问题看做一个区间,我们固定右端点之后只要找到一个下标最小的左端点就好了,
遍历这些数据顺便维护一个最小的左端点,当前标记大于这个最小值就更新答案,小于的话说明这个数找不到与他匹配的,更新最小标记。
固定右端点找id最小的左端点,显然我们不必要每次都重新找,只要从左至右循环顺便维护一下这个最小值就好了。
1 //排序做法 2 #include<bits/stdc++.h> 3 using namespace std; 4 struct node 5 { 6 int val,id; 7 bool operator<(const node &tmp)const{ 8 if(val!=tmp.val) return val<tmp.val; 9 return id<tmp.id; 10 } 11 }P[50005]; 12 int main() 13 { 14 int N,i,j,k,maxd=0; 15 scanf("%d",&N); 16 for(i=1;i<=N;++i) 17 { 18 scanf("%d",&P[i].val); 19 P[i].id=i; 20 }sort(P+1,P+1+N); 21 int mini=P[1].id; 22 for(i=1;i<=N;++i) 23 { 24 if(P[i].id<mini) mini=P[i].id; 25 else maxd=max(maxd,P[i].id-mini); 26 } 27 printf("%d\n",maxd); 28 return 0; 29 } 30 31 //ST做法 32 #include<bits/stdc++.h> 33 using namespace std; 34 struct SegTree 35 { 36 #define M ((L+R)>>1) 37 #define lc (id<<1) 38 #define rc (id<<1|1) 39 int maxv[50005<<2],A[50005],tot; 40 void init(){memset(maxv,0,sizeof(maxv));tot=0;} 41 void build(int L,int R,int id) 42 { 43 if(L==R){scanf("%d",&maxv[id]);A[++tot]=maxv[id];return;} 44 build(L,M,lc); 45 build(M+1,R,rc); 46 maxv[id]=max(maxv[lc],maxv[rc]); 47 } 48 int Find(int L,int R,int id,int v) 49 { 50 if(L==R) return L; 51 if(maxv[rc]>=v) return Find(M+1,R,rc,v); 52 else return Find(L,M,lc,v); 53 } 54 }seg; 55 int main() 56 { 57 int N,i,j,k,maxd=0; 58 scanf("%d",&N); 59 seg.init(); 60 seg.build(1,N,1); 61 for(i=1;i<=N;++i) 62 { 63 maxd=max(maxd,seg.Find(1,N,1,seg.A[i])-i); 64 } 65 printf("%d\n",maxd); 66 return 0; 67 }
标签:for eof 维护 star odi uil images UI codility
原文地址:http://www.cnblogs.com/zzqc/p/7406947.html