zoukankan      html  css  js  c++  java
  • 51nod 1272 思维/线段树

    http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1272

    1272 最大距离

    题目来源: Codility
    基准时间限制:1 秒 空间限制:131072 KB 分值: 20 难度:3级算法题
    收藏
    关注
    给出一个长度为N的整数数组A,对于每一个数组元素,如果他后面存在大于等于该元素的数,则这两个数可以组成一对。每个元素和自己也可以组成一对。例如:{5, 3, 6, 3, 4, 2},可以组成11对,如下(数字为下标):
    (0,0), (0, 2), (1, 1), (1, 2), (1, 3), (1, 4), (2, 2), (3, 3), (3, 4), (4, 4), (5, 5)。其中(1, 4)是距离最大的一对,距离为3。
    Input
    第1行:1个数N,表示数组的长度(2 <= N <= 50000)。
    第2 - N + 1行:每行1个数,对应数组元素Ai(1 <= Ai <= 10^9)。
    Output
    输出最大距离。
    Input示例
    6
    5
    3
    6
    3
    4
    2
    Output示例
    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
    ",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
    ",maxd);
    66     return 0;
    67 }
  • 相关阅读:
    绘图QPainter-画刷
    绘图QPainter-画笔
    pyqt5-多线程QThread类
    升级时出现错误的解决办法
    打包pyinstaller
    多文档界面QMdiArea
    停靠窗口QDockWidget
    堆叠窗口QStackedWidget
    VC运行库版本不同导致链接.LIB静态库时发生重复定义问题的一个案例分析和总结
    【一】ODB
  • 原文地址:https://www.cnblogs.com/zzqc/p/7406947.html
Copyright © 2011-2022 走看看