现在的位置: 首页 > 综合 > 正文

POJ 3264 Balanced Lineup 线段树基础

2018年04月04日 ⁄ 综合 ⁄ 共 1492字 ⁄ 字号 评论关闭

题意:

给出N个数M个询问,每个询问一个区间(a,b)。输出区间内最大值最小值的差值。

思路:

线段树,也可以RMQ。

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <string>
#include <cmath>
#include <cstring>
#include <queue>
#include <set>
#include <vector>
#include <stack>
#include <map>
#include <iomanip>
#define PI acos(-1.0)
#define Max 50005
#define inf 1<<28
using namespace std;

struct kdq
{
    int l,r;
    int max,min;//存最大值最小值
} tree[Max*4];
int n,m;
int cow[Max];
void build_tree(int l,int r,int u)//建树
{
    tree[u].l=l,tree[u].r=r;
    if(l==r)
    {
        tree[u].min=cow[l];
        tree[u].max=cow[l];
        return ;
    }
    int mid=(l+r)/2;
    build_tree(l,mid,u<<1);
    build_tree(mid+1,r,(u<<1)+1);
    tree[u].max=max(tree[u<<1].max,tree[(u<<1)+1].max);//更新最大值
    tree[u].min=min(tree[u<<1].min,tree[(u<<1)+1].min);//更新最小值
}
int querymax(int left,int right,int u)//寻找最大值
{
    if(tree[u].l==left&&tree[u].r==right)
        return tree[u].max;
    int mid=(tree[u].l+tree[u].r)/2;
    if(right<=mid)//插到左子树
        return querymax(left,right,u<<1);
    else if(left>mid)//插到右子树
        return querymax(left,right,(u<<1)+1);
    else
        return max(querymax(left,mid,u<<1),querymax(mid+1,right,(u<<1)+1));
}
int querymin(int left,int right,int u)//寻找最小值
{
    if(tree[u].l==left&&tree[u].r==right)
        return tree[u].min;
    int mid=(tree[u].l+tree[u].r)/2;
    if(right<=mid)
        return querymin(left,right,u<<1);
    else if(left>mid)
        return querymin(left,right,(u<<1)+1);
    else
        return min(querymin(left,mid,u<<1),querymin(mid+1,right,(u<<1)+1));
}
int main()
{
    int a,b;
    cin>>n>>m;
    for(int i=1; i<=n; i++)
        scanf("%d",&cow[i]);
    build_tree(1,n,1);
    while(m--)
    {
        scanf("%d%d",&a,&b);
        int max1=querymax(a,b,1);
        int min1=querymin(a,b,1);
        printf("%d\n",max1-min1);
    }
    return 0;
}

继续继续。

抱歉!评论已关闭.