线段树的尝试

先解释一下线段树的概念。

用数组模拟树,每个元素储存一段数据信息。

用递归生成。

常用来求解区间最值和区间和(区间和也可用前缀和)。

(笔者在poj 3264上尝试了未通过,可能还需要优化,有时间再搞)

此处给出对该题的尝试结果。

然后直接上代码,看注释。

#include<iostream>

#define max(x,y) ((x)>(y)?(x):(y))

#define min(x,y) ((x)<(y)?(x):(y))
using namespace std;

typedef struct node{
    int l;//区间左端点
    int r;//区间右端点
    int maxx;
    int minn;//区间最值

}node;
node a[400000];
int b[100000];
void build(int l,int r,int i)
{

    a[i].l=l;
    a[i].r=r;
    if(l==r)//如果是单点
    {
        a[i].l=a[i].r=l;
        a[i].maxx=a[i].minn=b[l];
        return;
    }
    int mid=(l+r)/2;//求中点
    build(l,mid,i<<1);//向左递归
    build(mid+1,r,i<<1|1);//向右递归
    a[i].maxx=max(a[i<<1].maxx,a[i<<1|1].maxx);//更新当前段
    a[i].minn=min(a[i<<1].minn,a[i<<1|1].minn);
    return;
}
int maxxx;//整体最值,此处用了全局变量也可以用返回值
int minnn;

void find(int x,int y,int i)
{
    if(x==a[i].l&&y==a[i].r)
    {
        maxxx=max(maxxx,a[i].maxx);//更新全局变量
        minnn=min(minnn,a[i].minn);

        return;
    }
    int mid=(a[i].l+a[i].r)>>2;
    if(x>mid)
    {
        find(x,y,i<<1|1);//向右找
    }
    else if(y<=mid)
    {
        find(x,y,i<<1);//向左找
    }
    else
    {
        find(x,mid,i<<1);//向左找
        find(mid+1,y,i<<1|1);//向右找
    }
}

int main()
{
    int n,m;
    cin>>n>>m;//n个元素,m次询问
    for(int i=1;i<=n;i++)
    {
        cin>>b[i];
    }
    build(1,n,1);
    int askx,asky;

    for(int i=0;i<m;i++)
    {
        cin>>askx>>asky;
        maxxx=0;
        minnn=1e9+7;//一个很大的数
        find(askx,asky,1);
        cout<<maxxx-minnn<<endl;

    }
}
 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值