kuangbin RMQ

  这是kuangbin的RMQ,一维的,代码很简洁,附上:

//kuangbin templet(查询最大值) 一维
//若想查最小,看提示更改
const int MAXN= 50000 + 9 ;
int dp[MAXN][20];//第二维是范围,即2^20约等于100万
//PS 如果同时要求最大最小,要多开一个dp2[][]来存最小
int mm[MAXN];//mm是间接存的数组

//b[]才是数据,并且b从1开始
void initRMQ(int n,int b[])
{
    mm[0]=-1;
    for (int i=1;i<=n;i++)
    {
        mm[i]=((i&(i-1))==0)?mm[i-1]+1:mm[i-1];
        dp[i][0]=b[i];
    }
    for (int j=1;j<=mm[n];j++)
        for (int i=1;i+(1<<j)-1<=n;i++)
            dp[i][j]=max(dp[i][j-1],dp[i+(1<<(j-1))][j-1]);
            //PS 若最小 max 改为 min
}
int RMQ(int x,int y)
{
    int k=mm[y-x+1];
    return max(dp[x][k],dp[y-(1<<k)+1][k]);
    //PS 若最小 max 改为 min
}

这是一个很好的测RMQ的题:http://poj.org/problem?id=3264

附上代码,initRMQ2和RMQ2是初始化最小,和查询最小的函数。

#include <stdio.h>
#include <iostream>
using namespace std;

const int INF=0x3f3f3f3f;
typedef long long ll;
#define PI(A) printf("%d\n",A)
#define SI(N) scanf("%d",&(N))
#define SII(N,M) scanf("%d%d",&(N),&(M))
#define cle(a,val) memset(a,(val),sizeof(a))
#define rep(i,b) for(int i=0;i<(b);i++)
#define Rep(i,a,b) for(int i=(a);i<=(b);i++)
#define reRep(i,a,b) for(int i=(a);i>=(b);i--)
const double EPS= 1e-9 ;

/*  /////////////////////////     C o d i n g  S p a c e     /////////////////////////  */

//kuangbin templet(查询最大值) 一维
//若想查最小,看提示更改
const int MAXN= 50000 + 9 ;
int dp[MAXN][20];//第二维是范围,即2^20约等于100万
int dp2[MAXN][20];
int mm[MAXN];

void initRMQ(int n,int b[])
{
    mm[0]=-1;
    for (int i=1;i<=n;i++)
    {
        mm[i]=((i&(i-1))==0)?mm[i-1]+1:mm[i-1];
        dp[i][0]=b[i];
    }
    for (int j=1;j<=mm[n];j++)
        for (int i=1;i+(1<<j)-1<=n;i++)
            dp[i][j]=max(dp[i][j-1],dp[i+(1<<(j-1))][j-1]);
            //PS 若最小 max 改为 min
}
int RMQ(int x,int y)
{
    int k=mm[y-x+1];
    return max(dp[x][k],dp[y-(1<<k)+1][k]);
    //PS 若最小 max 改为 min
}
void initRMQ2(int n,int b[])
{
    mm[0]=-1;
    for (int i=1;i<=n;i++)
    {
        mm[i]=((i&(i-1))==0)?mm[i-1]+1:mm[i-1];
        dp2[i][0]=b[i];
    }
    for (int j=1;j<=mm[n];j++)
        for (int i=1;i+(1<<j)-1<=n;i++)
            dp2[i][j]=min(dp2[i][j-1],dp2[i+(1<<(j-1))][j-1]);
            //PS 若最小 max 改为 min
}
int RMQ2(int x,int y)
{
    int k=mm[y-x+1];
    return min(dp2[x][k],dp2[y-(1<<k)+1][k]);
    //PS 若最小 max 改为 min
}
int N,Q;
int input[MAXN];
int main()
{
    while(~SII(N,Q))
    {
        Rep(i,1,N) SI(input[i]);
        initRMQ(N,input);
        initRMQ2(N,input);
        rep(i,Q)
        {
            int a,b;
            SII(a,b);
            printf("%d\n",RMQ(a,b)-RMQ2(a,b));
        }
    }

    return 0;
}
时间: 2024-11-06 03:36:40

kuangbin RMQ的相关文章

HDU 4122 Alice&#39;s mooncake shop --RMQ

题意: 一个月饼店做月饼,总营业时间m小时,只能在整点做月饼,可以做无限个,不过在不同的时间做月饼的话每个月饼的花费是不一样的,假设即为cost[i],再给n个订单,即为在某个时间要多少个月饼,时间从2000年1月1日0时开始计算,必须在每个订单的时间之前完成这么多月饼,月饼还有保质期T小时以及保存费用S每小时,现在问满足这n个点的最小成本是多少. 解法: 因为月饼有保质期T,所以第i个月饼只能在[Ti-T+1,Ti]时间内做好.如果时间j有订单,假设在时间i做月饼是最好的,那么这个订单每个月饼

RMQ、POJ3264

这里说几篇博客,建议从上到下看 https://blog.csdn.net/qq_31759205/article/details/75008659 https://blog.csdn.net/sgh666666/article/details/80448284 https://www.cnblogs.com/kuangbin/p/3227420.html ----------------------------------------------------------------------

「kuangbin带你飞」专题十八 后缀数组

layout: post title: 「kuangbin带你飞」专题十八 后缀数组 author: "luowentaoaa" catalog: true tags: - kuangbin - 字符串 - 后缀数组 传送门 倍增法 struct DA{ bool cmp(int *r,int a,int b,int l){ return r[a]==r[b]&&r[a+l]==r[b+l]; } int t1[maxn],t2[maxn],c[maxn]; int r

dutacm.club 1094: 等差区间(RMQ区间最大、最小值,区间GCD)

1094: 等差区间 Time Limit:5000/3000 MS (Java/Others)   Memory Limit:163840/131072 KB (Java/Others)Total Submissions:655   Accepted:54 [Submit][Status][Discuss] Description 已知一个长度为 n 的数组 a[1],a[2],-,a[n],我们进行 q 次询问,每次询问区间 a[l],a[l+1],-,a[r?1],a[r] ,数字从小到大

RMQ问题再临

RMQ问题再临 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 终于,小Hi和小Ho踏上了回国的旅程.在飞机上,望着采购来的特产——小Hi陷入了沉思:还记得在上上周他们去超市的时候,前前后后挑了那么多的东西,都幸运的没有任何其他人(售货员/其他顾客)来打搅他们的采购过程.但是如果发生了这样的事情,他们的采购又会变得如何呢? 于是小Hi便向小Ho提出了这个问题:假设整个货架上从左到右摆放了N种商品,并且依次标号为1到N,每次小Hi都给出一段区间[L, R],小Ho要做

[bzoj3489]A simple rmq problem

本题既不是rmq也不会simple(对我这种蒟蒻而言) 一开始只能想到树套树套树TAT然后看了看数据范围果断滚去膜拜题解. 然后才知道预先排序一下可以弄掉一个log.不过得写可持久化线段树套可持久化线段树.. 然后愉悦的开码了...感人的是竟然不用调...更感人的是交上去直接tle了. 然后从网上找了别人的代码(方法一样)发现同样的数据我要跑6s+..标称只要2s+.. 之后各种卡常还是慢了一倍TAT...最后自己写个max函数就和标程一样快了TAT这几天怎么总是出些奇怪的状况QAQ. 本来故事

CodeForces 514D R2D2 and Droid Army RMQ+二分

题目链接:点击打开链接 题意:给定n m k 下面是n*m的矩阵 最多可以操作k次,每次操作可以使任意一列上所有的数 -= 1,( 0还是0) 要求得到连续最多的行数(每行里的整数都为0),输出任意一个方案(在每一列上操作的次数) 思路: 把每列单独考虑 枚举每行,二分找这行往下最多能清空的行数, RMQ维护一列的最大值. import java.io.BufferedReader; import java.io.InputStreamReader; import java.io.PrintWr

poj 3264 Balanced Lineup RMQ线段树实现

Balanced Lineup Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 36613   Accepted: 17141 Case Time Limit: 2000MS Description For the daily milking, Farmer John's N cows (1 ≤ N ≤ 50,000) always line up in the same order. One day Farmer Joh

湖南省第七届大学生计算机程序设计竞赛 RMQ with Shifts (线段树)

RMQ with Shifts 时间限制:1000 ms  |  内存限制:65535 KB 难度:3 描述     In the traditional RMQ (Range Minimum Query) problem, we have a static array A. Then for each query (L, R) (L<=R), we report the minimum value among A[L], A[L+1], -, A[R]. Note that the indic