POJ 3264 Balanced Lineup 线段树的构建+区间查询

来源:互联网 发布:伪造短信软件 编辑:程序博客网 时间:2024/06/10 21:14

第一次写线段树,能写出来感觉很开心。。。

这道题属于最简单的线段树问题,只有建树与区间查询两大模块,后来我把单点更新的部分去掉了,建树如果用单点更新的方法的话效率有点低。

首先说一下我的线段树风格,我采用的是左闭右开区间,结点序号从1开始,数组的0号元素空出来了,原因是这样的话可以用位运算很方便地表示两个儿子结点的序号,如果从0开始貌似得用加减运算了,有点慢。

//Run IDUserProblemResultMemoryTimeLanguageCode LengthSubmit Time//13076065ritying3264Accepted1164K2297MSC++1850B2014-07-14 15:44:05#include <cstdio>#include <iostream>#include <cstring>#include <climits>using namespace std;#define lson(x) ((x)<<1)#define rson(x) ((x)<<1 | 1)const int MAXN = 50000;const int INF = INT_MAX;int dat1[4*MAXN], dat2[4*MAXN]; //如果不幸运的话叶子节点将会是原来的两倍,再加上中间节点所以一共是4倍(如果结点序号从1开始的话理论上是4*MAXN-4)int n, N, Q;void init(int N){    n = 1;    while(n < N) n <<= 1;    for(int i=1; i<=n; i++){        dat1[i] = INF;        dat2[i] = 0;    }}inline void PushUp(int rt){    dat1[rt] = min(dat1[lson(rt)], dat1[rson(rt)]);    dat2[rt] = max(dat2[lson(rt)], dat2[rson(rt)]);}void build(int rt, int l, int r){    if(l+1 == r){        if(l <= N){           scanf("%d", &dat1[rt]);           dat2[rt] = dat1[rt];        }        else{            dat1[rt] = INF;            dat2[rt] = 0;        }        return;    }    build(lson(rt), l, (l+r)>>1);    build(rson(rt), (l+r)>>1, r);    PushUp(rt);}int querymin(int a, int b, int k, int l, int r){    if(b <= l || r <= a) return INF;    else if(a <= l && r <= b) return dat1[k];    else{        int vl = querymin(a, b, lson(k), l, (l+r)>>1);        int vr = querymin(a, b, rson(k), (l+r)>>1, r);        return min(vl, vr);    }}int querymax(int a, int b, int k, int l, int r){    if(b <= l || r <= a) return 0;    else if(a <= l && r <= b) return dat2[k];    else{        int vl = querymax(a, b, lson(k), l, (l+r)>>1);        int vr = querymax(a, b, rson(k), (l+r)>>1, r);        return max(vl, vr);    }}int main(){    while(scanf("%d %d", &N, &Q) != EOF){       init(N);       build(1, 1, n+1);       while(Q--){           int a, b;           scanf("%d %d", &a, &b);           int low = querymin(a, b+1, 1, 1, n+1);           int high = querymax(a, b+1, 1, 1, n+1);           printf("%d\n", high - low);       }    }    return 0;}


0 0
原创粉丝点击