zoukankan      html  css  js  c++  java
  • [RMQ]板题

    水题链接

    既然是板题了,肯定是来练模板的。

    何为RMQ

    RMQ实际就是一个区间找最值的东西,说道区间找最值,我们最喜爱暴力了。同时还可以用线段树这一数据结构,但,如果询问次数比较多,就爆j炸了,众所周知,线段树查询的速度是log,询问多肯定会炸,我们需要O(1)的查询速度

    所以,就可以用好用的RMQ了。但不足的是,RMQ的预处理时间要比线段树大,因此我们要根据数据范围谨慎操作。

    我们设dp[i][j]表示从i开始,走2^j的这一段路中的最大值。我们就需要转移。

    for (int j = 1;(1 << j) <= 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]);

    很好理解,其实就是i点走2^j - 1的最大值与i走2^(j - 1)再走2^(j - 1)比较取最大。

    解题思路

    那么这道题其实没啥意思,就是一个最大,一个最小,再相减即可。

    我们直接套模板可以做出来。

    但其实我们虽然构造好了,但我们还要思考如何返回值。

    我们定义变量k,k = log(r - l + 1)。

    那么dp[l][k]就是l到l + 2^k - 1这一段区间,dp[r - (1 << k )+ 1][k]则是r - 2^k + 1 到r这一段区间。

    可以证明,这一段区间肯定是完全包含l到r这一段区间的,因此就可以做出来。

    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<iostream>
    #include<algorithm>
    #include<queue>
    #include<vector>
    #include<cstdlib>
    using namespace std;
    int n,t,a[50005],dp[50005][31],dp1[50005][31];
    void make(){
    	for (int i = 1;i <= n;i ++){
    		dp[i][0] = a[i];
    		dp1[i][0] = a[i];
    	}
    	for (int j = 1;(1 << j) <= 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]);
    			dp1[i][j] = min(dp1[i][j - 1],dp1[i + (1 << j - 1)][j - 1]);
    		}
    	}
    }
    int find(int l,int r){
    	int k = int (log(double(r - l + 1)) / log(2.0));
    	return max(dp[l][k],dp[r - (1 << k) + 1][k]) - min(dp1[l][k],dp1[r - (1 << k) + 1][k]);
    }
    int main(){
    	scanf ("%d%d",&n,&t);
    	for (int i = 1;i <= n;i ++)
    		scanf ("%d",&a[i]);
    	make();
    	while (t --){
    		int l,r;
    		scanf ("%d%d",&l,&r);
    		printf("%d
    ",find(l,r));
    	}
    }
  • 相关阅读:
    C++中的模板编程
    C++中的抽象类
    C++中的多态
    C++中的继承
    操作符重载(二)
    操作符重载(一)
    C++中的类与对象模型
    [八省联考2018] 劈配 (网络流+二分)
    CF51F Caterpillar (边双+树形DP)
    CF36E Two Paths (欧拉回路+构造)
  • 原文地址:https://www.cnblogs.com/lover-fucker/p/13566677.html
Copyright © 2011-2022 走看看