码迷,mamicode.com
首页 > 其他好文 > 详细

XDOJ_1010_rmq

时间:2016-10-13 23:42:12      阅读:132      评论:0      收藏:0      [点我收藏+]

标签:

http://acm.xidian.edu.cn/problem.php?id=1010

 

可以把序列分为左右两部分,ab在左,cd在右,至于怎么找左右的最大差值,我用了rmq。

然后枚举两部分的中间位置就可以了。

 

#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<cmath>
#define INF 0x3f3f3f3f
using namespace std;

int maxdp[100005][20],mindp[100005][20],lmax[100005],rmax[100005],a[100005],n;

void rmq_init(int len)
{
    for(int i = 1;i <= len;i++)
    {
        maxdp[i][0] = a[i];
        mindp[i][0] = a[i];
    }
    for(int j = 1;(1<<j) <= len;j++)
    {
        for(int i = 1;i+(1<<j)-1 <= len;i++)
        {
            maxdp[i][j] = max(maxdp[i][j-1],maxdp[i+(1<<(j-1))][j-1]);
            mindp[i][j] = min(mindp[i][j-1],mindp[i+(1<<(j-1))][j-1]);
        }
    }
}

int rmq_max(int l,int r)
{
    int k = (int)(log((double)(r-l+1))/log(2.0));
    return max(maxdp[l][k],maxdp[r-(1<<k)+1][k]);
}

int rmq_min(int l,int r)
{
    int k = (int)(log((double)(r-l+1))/log(2.0));
    return min(mindp[l][k],mindp[r-(1<<k)+1][k]);
}

int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d",&n);
        for(int i = 1;i <= n;i++)   scanf("%d",&a[i]);
        rmq_init(n);
        int tempmax = -INF,minnum = a[1],minpos = 1;
        for(int i = 1;i < n;i++)
        {
            if(a[i] < minnum)
            {
                minnum = a[i];
                minpos = i;
            }
            int temp = rmq_max(minpos+1,i+1)-minnum;
            tempmax = max(temp,tempmax);
            lmax[i+1] = tempmax;
        }
        tempmax = -INF;
        int maxnum = a[n],maxpos = n;
        for(int i = n;i > 1;i--)
        {
            if(a[i] > maxnum)
            {
                maxnum = a[i];
                maxpos = i;
            }
            int temp = maxnum-rmq_min(i-1,maxpos-1);
            tempmax = max(temp,tempmax);
            rmax[i-1] = tempmax;
        }
        int ans = -INF;
        for(int i = 2;i < n-2;i++)  ans = max(lmax[i]+rmax[i+1],ans);
        printf("%d\n",ans);
    }
    return 0;
}

 

XDOJ_1010_rmq

标签:

原文地址:http://www.cnblogs.com/zhurb/p/5958488.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!