poj3264------线段树

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了poj3264------线段树相关的知识,希望对你有一定的参考价值。

题目大意:

有N个点,Q次查询,每次查询区间内的最大值和最小值之差

思路: 线段树

代码:

#include <iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int MAX = 200000+5;
int N,Q,a[MAX];
int ansMin,ansMax;
struct Tree
{
    int l,r,mins,maxs;
}tree[4*MAX];
///建立线段树,cnt为节点角标,a[l]-a[r]建树
void build(int cnt,int l,int r)
{
    tree[cnt].l = l,tree[cnt].r = r;
    if(l==r)
    {
        tree[cnt].mins = tree[cnt].maxs = a[l];
        return;
    }
    int mid = (l + r)/2;
    build(2*cnt,l,mid);
    build(2*cnt+1,mid+1,r);
    ///回溯建立父节点
    tree[cnt].mins = min(tree[2*cnt].mins,tree[2*cnt+1].mins);
    tree[cnt].maxs = max(tree[2*cnt].maxs,tree[2*cnt+1].maxs);


}
///查询区间l-r的最大值和最小值
void query(int cnt,int l,int r)
{
    if(tree[cnt].mins>=ansMin&&tree[cnt].maxs<=ansMax)
        return;
    if(tree[cnt].l==l&&tree[cnt].r==r)
    {
        ansMax = max(tree[cnt].maxs,ansMax), ansMin = min(tree[cnt].mins,ansMin);
        return;
    }
    ///分三种情况讨论
    int mid = (tree[cnt].l+tree[cnt].r)/2;
    if(r<=mid)///在mid右端
        query(2*cnt,l,r);
    else if(l>mid)///在mid左端
        query(2*cnt+1,l,r);
    else///两端
    {
        query(2*cnt,l,mid);
        query(2*cnt+1,mid+1,r);
    }

}
int main()
{
    //freopen("in.txt","r",stdin);
    while(scanf("%d%d",&N,&Q)!=EOF)
    {
        memset(tree,0,sizeof(tree));
        for(int i=1;i<=N;i++)
            scanf("%d",&a[i]);
        int left,right;
        build(1,1,N);
        for(int i=1;i<=Q;i++)
        {
            ansMin = 0x3f3f3f3f, ansMax = -1;
            scanf("%d%d",&left,&right);
            query(1,left,right);
            printf("%d\n",ansMax-ansMin);
        }
    }
    return 0;
}

 

以上是关于poj3264------线段树的主要内容,如果未能解决你的问题,请参考以下文章

POJ - 3264(线段树实现)

poj3264 线段树

POJ3264-Balanced Lineup-线段树

poj 3264 线段树

POJ 3264 Balanced Lineup(线段树 区间最值)

[POJ 3264] Balanced Lineup [线段树]