RMQ //poj3264,poj3368

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;
}
时间: 2024-11-05 13:39:09

RMQ //poj3264,poj3368的相关文章

acm常见算法及例题

转自:http://blog.csdn.net/hengjie2009/article/details/7540135 acm常见算法及例题 初期:一.基本算法:     (1)枚举. (poj1753,poj2965)     (2)贪心(poj1328,poj2109,poj2586)     (3)递归和分治法.     (4)递推.     (5)构造法.(poj3295)     (6)模拟法.(poj1068,poj2632,poj1573,poj2993,poj2996)二.图算法

ACM算法总结及刷题参考

参考:http://bbs.byr.cn/#!article/ACM_ICPC/11777 OJ上的一些水题(可用来练手和增加自信)(poj3299,poj2159,poj2739,poj1083,poj2262,poj1503,poj3006,poj2255,poj3094) 初期: 一.基本算法: (1)枚举. (poj1753,poj2965)    (2)贪心(poj1328,poj2109,poj2586)    (3)递归和分治法.     (4)递推.     (5)构造法.(po

POJ题目推荐(转载)

POJ推荐50题1.标记“难”和“稍难”的题目可以看看,思考一下,不做要求,当然有能力的同学可以直接切掉.2.标记为A and B的题目是比较相似的题目,建议大家两个一起做,可以对比总结,且二者算作一个题目.3.列表中大约有70个题目.大家选做其中的50道,且每类题目有最低数量限制.4.这里不少题目在BUPT ACM FTP上面都有代码,请大家合理利用资源.5.50个题目要求每个题目都要写总结,养成良好的习惯.6.这个列表的目的在于让大家对各个方面的算法有个了解,也许要求有些苛刻,教条,请大家谅

POJ题目分类

初期: 一.基本算法:     (1)枚举. (poj1753,poj2965)     (2)贪心(poj1328,poj2109,poj2586)     (3)递归和分治法.     (4)递推.     (5)构造法.(poj3295)     (6)模拟法.(poj1068,poj2632,poj1573,poj2993,poj2996)二.图算法:     (1)图的深度优先遍历和广度优先遍历.     (2)最短路径算法(dijkstra,bellman-ford,floyd,he

嗷嗷嗷,kuangbin大大博客上拉的题

正在学(learning),未学(waiting),已学(cut  vovering) 初期:一.基本算法:     (1)枚举. (poj1753,poj2965)     (2)贪心(poj1328,poj2109,poj2586)     (3)递归和分治法.     (4)递推.     (5)构造法.(poj3295)     (6)模拟法.(poj1068,poj2632,poj1573,poj2993,poj2996)二.图算法:     (1)图的深度优先遍历和广度优先遍历.  

转:转一个搞ACM需要的掌握的算法. .

要注意,ACM的竞赛性强,因此自己应该和自己的实际应用联系起来.  适合自己的才是好的,有的人不适合搞算法,喜欢系统架构,因此不要看到别人什么就眼红,  发挥自己的长处,这才是重要的. 第一阶段:练经典常用算法,下面的每个算法给我打上十到二十遍,同时自己精简代码,  因为太常用,所以要练到写时不用想,10-15分钟内打完,甚至关掉显示器都可以把程序打  出来.  1.最短路(Floyd.Dijstra,BellmanFord)  2.最小生成树(先写个prim,kruscal要用并查集,不好写)

算法初学者指南

摘自网络,对于这个训练计划,我只能膜拜,~ 第一阶段:练经典常用算法,下面的每个算法给我打上十到二十遍,同时自己精简代码, 因为太常用,所以要练到写时不用想,10-15 分钟内打完,甚至关掉显示器都可以把程序打 出来. 1.最短路(Floyd.Dijstra,BellmanFord) 2. 最小生成树(先写个prim,kruscal要用并查集,不好写) 3.大数(高精度)加减乘除 4.二分查找. (代码可在五行以内) 5.叉乘.判线段相交.然后写个凸包. 6.BFS.DFS,同时熟练hash表(

POJ分类

初期: 一.基本算法: (1)枚举. (poj1753,poj2965) (2)贪心(poj1328,poj2109,poj2586) (3)递归和分治法. (4)递推. (5)构造法.(poj3295) (6)模拟法.(poj1068,poj2632,poj1573,poj2993,poj2996) 二.图算法: (1)图的深度优先遍历和广度优先遍历. (2)最短路径算法(dijkstra,bellman-ford,floyd,heap+dijkstra) (poj1860,poj3259,p

超强的ACM题目类型总结

转:初期: 一.基本算法:       (1)枚举. (poj1753,poj2965)     (2)贪心(poj1328,poj2109,poj2586)     (3)递归和分治法.       (4)递推.       (5)构造法.(poj3295)     (6)模拟法.(poj1068,poj2632,poj1573,poj2993,poj2996) 二.图算法:       (1)图的深度优先遍历和广度优先遍历.       (2)最短路径算法(dijkstra,bellman-