POJ 3264 Balanced Lineup(ST)

来源:互联网 发布:淘宝助理打开没有 编辑:程序博客网 时间:2024/06/05 01:02

Description
在一组数中,查询某个区间内的最大数与最小数的差
Input
第一行两个整数n和q分别表示数的个数和查询次数,之后n行每行一个整数表示该数列,最后q行每行两个整数a,b表示查询区间
Output
对于每次查询,输出该区间内最值之差
Sample Input
6 3
1
7
3
4
2
5
1 5
4 6
2 2
Sample Output
6
3
0
Solution
ST算法,大概的意思就是动态规划,以求最大值为例子,Max[i][j],代表的是从第i个开始,到第2^j个中最大的,显然Max[i][0]=a[i],即那个数本身。状态转移方程为:
Max[i][j]=max(Max[i][j-1],Max[i+(1<<(j-1))][j-1]),
意思很明显,就是前半段和后半段的最大值,[i ,2^(j-1)], [2^(j-1),j]的最大值.
Code

#include<cstdio>#include<cstring>#include<iostream>#include<cmath>using namespace std;#define maxn 200010int n,q;int l,r;int hmin[maxn][20],hmax[maxn][20];void init(){    int k=(int)(log(n*1.0)/log(2.0));    for(int j=1;j<=k;j++)        for(int i=0;i+(1<<j)<=n;i++)        {            hmin[i][j]=min(hmin[i][j-1],hmin[i+(1<<(j-1))][j-1]);            hmax[i][j]=max(hmax[i][j-1],hmax[i+(1<<(j-1))][j-1]);        }}int main(){    while(scanf("%d%d",&n,&q)!=EOF)    {        for(int i=0;i<n;i++)        {            scanf("%d",&hmin[i][0]);            hmax[i][0]=hmin[i][0];        }        init();        while(q--)        {            scanf("%d%d",&l,&r);            l--;r--;            int k=(int)(log((r-l+1)*1.0)/log(2.0));            int ans1=min(hmin[l][k],hmin[r-(1<<k)+1][k]);            int ans2=max(hmax[l][k],hmax[r-(1<<k)+1][k]);            printf("%d\n",ans2-ans1);        }    }    return 0;}
0 0
原创粉丝点击