• 【poj3264】 Balanced Lineup


    http://poj.org/problem?id=3264 (题目链接)

    题意

      给出序列,求区间最大值-最小值

    Solution

      无修改,询问较多,ST表水一发。

    ST算法(Sparse Table):

      它是一种动态规划的方法。以最小值为例。a为所寻找的数组,用一个二维数组 f(i,j) 记录区间 [i,i+2^j-1] 区间中的最小值。其中 f[i,0] = a[i] ; 所以,对于任意的一组 (i,j),f(i,j) = min{ f(i,j-1),f(i+2^(j-1),j-1)} 来使用动态规划计算出来。

      这个算法的高明之处不是在于这个动态规划的建立,而是它的查询:它的查询效率是O(1)!如果不细想的话,怎么弄也是不会想到有O(1)的算法的。

      假设我们要求区间[m,n]中a的最小值,找到一个数k使得2^k<n-m+1,即k=[ln(b-a+1)/ln(2)] 这样,可以把这个区间分成两个部分:[m,m+2^k-1]和[n-2^k+1,n]!我们发现,这两个区间是已经初始化好的!前面的区间是f(m,k),后面的区间是f(n-2^k+1,k)!这样,只要看这两个区间的最小值,就可以知道整个区间的最小值!

    代码

    // poj3264
    #include<algorithm>
    #include<iostream>
    #include<cstdlib>
    #include<cstring>
    #include<cstdio>
    #include<cmath>
    #define LL long long
    #define inf 2147483640
    #define Pi acos(-1.0)
    #define free(a) freopen(a".in","r",stdin),freopen(a".out","w",stdout);
    using namespace std;
    
    const int maxn=50010;
    int bin[30],a[maxn],mn[maxn][30],mx[maxn][30];
    int n,m;
    
    void build() {
    	for (int i=1;i<=n;i++) mx[i][0]=mn[i][0]=a[i];
    	for (int j=1;j<=20;j++)
    		for (int i=1;i+bin[j]<=n+1;i++)
    			mn[i][j]=min(mn[i][j-1],mn[i+bin[j-1]][j-1]);
    	for (int j=1;j<=20;j++)
    		for (int i=1;i+bin[j]<=n+1;i++)
    			mx[i][j]=max(mx[i][j-1],mx[i+bin[j-1]][j-1]);
    }
    int query(int l,int r) {
    	int x=log(r-l+1)/log(2);
    	int a=max(mx[l][x],mx[r-bin[x]+1][x]);
    	int b=min(mn[l][x],mn[r-bin[x]+1][x]);
    	return a-b;
    }
    int main() {
    	bin[0]=1;for (int i=1;i<=20;i++) bin[i]=bin[i-1]<<1;
    	scanf("%d%d",&n,&m);
    	for (int i=1;i<=n;i++) scanf("%d",&a[i]);
    	build();
    	for (int x,y,i=1;i<=m;i++) {
    		scanf("%d%d",&x,&y);
    		printf("%d
    ",query(x,y));
    	}
    	return 0;
    }
    

      

  • 相关阅读:
    第一次Java测试及感触
    第七周学习
    第六周学习
    第5周学习
    第四周学习
    第三周学习
    浅略学习
    读完《大道至简》后的小感悟
    初识JAVA
    Java课后作业之石家庄地铁系统PSP表格20190403
  • 原文地址:https://www.cnblogs.com/MashiroSky/p/5943558.html
Copyright © 2020-2023  润新知