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

RMQ //poj3264,poj3368

时间:2015-07-25 18:02:55      阅读:129      评论:0      收藏:0      [点我收藏+]

标签:

http://poj.org/problem?id=3264

#include<iostream>
#include<cstdio>
#include<string>
#include<cmath>
#include<cstring>
#define M 1000000 + 50
using namespace std;
int a[M];
int maxs[M][100];
int mins[M][100];

int QueryMax(int L, int R)
{
    int k = log(R - L + 1.0) / log(2.0);
    return max(maxs[L][k], maxs[R - (1 << k) + 1][k]);
}

int QueryMin(int L, int R)
{
    int k = log(R - L + 1.0) / log(2.0);
    return min(mins[L][k], mins[R - (1 << k) + 1][k]);
}

int main()
{
    //freopen("in.txt","r",stdin);
    int n, q;
    scanf("%d%d", &n, &q);
    for (int i = 1; i <= n; i++)
        scanf("%d", &a[i]);
    int dep = log(n * 1.0) / log(2.0);
    for (int i = 1; i <= n; i++)
    {
        mins[i][0] = a[i];
        maxs[i][0] = a[i];
    }
    for (int j = 1; j <= dep; j++)
    {
        for (int i = 1; i + (1 << j) - 1 <= n; i++)
        {
            maxs[i][j] = max(maxs[i][j - 1], maxs[i + (1 << (j - 1))][j - 1]);
            mins[i][j] = min(mins[i][j - 1], mins[i + (1 << (j - 1))][j - 1]);
        }
    }
    int l, r;
    for (int i = 1; i <= q; i++)
    {
        scanf("%d%d", &l, &r);
        int maxn = QueryMax(l, r);
        int minn = QueryMin(l, r);
        printf("%d\n", maxn - minn);
    }
    return 0;
}

http://poj.org/problem?id=3368

查询断点处的数据值在区间[i,j]出现了k2 - k1 - 1 次;

求max(左边区间出现相同数字最多的次数,右边区间出现相同数字最多次数,k2 - k1 - 1);

有两个地方均需要此处理;

#include <iostream>
#include <algorithm>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <string>
#include <math.h>
#include <time.h>
#include <vector>
#include <map>
#include <set>
#define M 100000 + 50
using namespace std;
int a[M];
int maxn[M][30];

int QueryMax(int L, int R)
{
    int k = log(R - L + 1.0) / log(2.0);
    int maxs = max(maxn[L][k], maxn[R - (1 << k) + 1][k]);
    int k1 = R - (1 << k) + 1, temp = a[k1], k2 = k1;
    while (a[k1] == temp && k1 >= L) k1--;
    while (a[k2] == temp && k2 <= R) k2++;
    maxs = max(maxs, k2 - k1 - 1);
    return maxs;
}

int main()
{
    //freopen("in.txt","r",stdin);
    int n, q;
    while (scanf("%d", &n) && n)
    {
        memset(a, 0, sizeof(a));
        scanf("%d", &q);
        for (int i = 1; i <= n; i++)        scanf("%d", &a[i]);
        for (int i = 1; i <= n; i++)        maxn[i][0] = 1;
        int dep = log(n * 1.0) / log(2.0);
        for (int j = 1; j <= dep; j++)
        {
            for (int i = 1; i + (1 << j) - 1 <= n; i++)
            {
                maxn[i][j] = max(maxn[i][j - 1], maxn[i + (1 << (j - 1))][j - 1]);
                int k1 = i + (1 << (j - 1)), temp = a[k1], k2 = k1;
                while (a[k1] == temp && k1 >= i) k1--;
                while (a[k2] == temp && k2 < i + (1 << j)) k2++;
                maxn[i][j] = max(maxn[i][j], k2 - k1 - 1);
            }
        }
        int l, r;
        for (int i = 0; i < q; i++)
        {
            scanf("%d%d", &l, &r);
            printf("%d\n", QueryMax(l, r));
        }
    }
    return 0;
}

 

RMQ //poj3264,poj3368

标签:

原文地址:http://www.cnblogs.com/zouqihan/p/4676186.html

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