POJ 3264 線段樹求區間最大最小值
阿新 • • 發佈:2018-11-10
很裸的線段樹,沒有什麼好說的,我把根節點所擁有的左右區間都寫在結構體裡面,這樣傳參的時候比較方便。
POJ不支援萬能頭很不習慣。
#include<iostream> #include<cstdio> using namespace std; const int maxn=5e4+50,inf=0x3f3f3f3f; int a[maxn],ans1,ans2;struct node{ int l,r,maxx,minn; }s[maxn<<2]; void build(int root,int l,int r) { s[root].l=l,s[root].r=r,s[root].maxx=-1,s[root].minn=inf; if(l==r) { s[root].maxx=s[root].minn=a[l];return;} int mid=(l+r)>>1; build(root<<1,l,mid); build(root<<1|1,mid+1,r); s[root].maxx=max(s[root<<1].maxx,s[root<<1|1].maxx); s[root].minn=min(s[root<<1].minn,s[root<<1|1].minn); } void query(int root,int l,int r) { if(s[root].l==l&&s[root].r==r) {ans1=max(ans1,s[root].maxx),ans2=min(ans2,s[root].minn);return;} int mid=(s[root].l+s[root].r)>>1; if(r<=mid) query(root<<1,l,r); else if(l>=mid+1) query(root<<1|1,l,r); else { query(root<<1,l,mid); query(root<<1|1,mid+1,r); } } int main() { int n,m,l,r; scanf("%d%d",&n,&m); for(int i=1;i<=n;++i) scanf("%d",&a[i]); build(1,1,n); for(int i=1;i<=m;++i){ scanf("%d%d",&l,&r);ans1=-1,ans2=0x3f3f3f3f; query(1,l,r);printf("%d\n",ans1-ans2); } return 0; }