POJ3264线段树求最值
Posted brotherhood
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了POJ3264线段树求最值相关的知识,希望对你有一定的参考价值。
刚开始还觉得有点怪怪的。因为想着如果每个树只是单纯地记录它所在的区间的话会不会有不在区间内的数据给更新了,但是我好像是傻掉了因为如果有这种情况出现的话在父亲节点就会分成l,mid和mid+1,r两个区间查找,当节点区间和查找的区间完全吻合时就ok了。
这道题没有修改,连懒标记都不需要,是一道实打实的板子我却浪费了这么长时间我恨我自己
#include<iostream> #include<cstdio> #include<algorithm> #include<ctype.h> #include<cstring> using namespace std; const int maxn=50005; inline int read() { int x=0,w=0;char c=getchar(); while(!isdigit(c))w|=c==‘-‘,c=getchar(); while(isdigit(c))x=(x<<3)+(x<<1)+(c^48),c=getchar(); return w?-x:x; } struct SegmentTree { struct Node{ int l,r; int mx,mn; int tagmx,tagmn; }e[4*maxn]; #define ls (ro<<1) #define rs (ro<<1|1) #define INF 0x3f3f3f3f int maxx,minn; int n,m; void build(int ro,int l,int r) { e[ro].l=l,e[ro].r=r; e[ro].mn=INF,e[ro].mx=-INF; if(l==r)return ; int mid=(l+r)>>1; build(ls,l,mid); build(rs,mid+1,r); } void insert(int ro,int i,int k) { if(e[ro].l==e[ro].r){ e[ro].mx=e[ro].mn=k;return; } e[ro].mn=min(e[ro].mn,k); e[ro].mx=max(e[ro].mx,k); int mid=(e[ro].l+e[ro].r)>>1; if(i<=mid)insert(ls,i,k); else insert(rs,i,k); } void query(int ro,int l,int r) { if(e[ro].mn>=minn and e[ro].mx<=maxx)return ; if(e[ro].l==l and e[ro].r==r){ minn=min(minn,e[ro].mn); maxx=max(maxx,e[ro].mx); return; } int mid=(e[ro].l+e[ro].r)>>1; if(r<=mid)query(ls,l,r); else if(l>mid)query(rs,l,r); else {query(ls,l,mid);query(rs,mid+1,r);} } inline void getans() { n=read();m=read(); build(1,1,n); for(int i=1;i<=n;i++) insert(1,i,read()); for(int i=1;i<=m;i++) { maxx=-INF,minn=INF; int l=read(),r=read(); query(1,l,r); printf("%d ",maxx-minn); } return ; } #undef ls #undef rs #undef INF }st; int main() { st.getans(); return 0; }
用一下结构体~
以上是关于POJ3264线段树求最值的主要内容,如果未能解决你的问题,请参考以下文章
POJ 3264 Balanced Lineup(线段树 区间最值)