poj之旅——3264

来源:互联网 发布:linux打开摄像头命令 编辑:程序博客网 时间:2024/05/22 23:37

//2886又没理解,诶诶,语言障碍

题目描述:给出n个人的升高,有T个询问【i,j】,求从i到j最高-最矮的差。


题解:典型的rmq问题,hankcs用的平方分割(术语称:块状数组),不喜欢,自己打的Square—Table算法,和线段树练练手。


参考程序:

ST:

#include<cstdio>#include<algorithm>#define maxn 51000using namespace std;int a[maxn];int n,q;struct RMQ{int n;void init(int n){this->n=n;}int Max[maxn][30];int Min[maxn][30];void prepare(){for (int i=0;i<n;i++)Max[i][0]=a[i],Min[i][0]=a[i];for (int j=1;(1<<j)<=n;j++)for (int i=0;i+(1<<j)<=n;i++){Max[i][j]=max(Max[i][j-1],Max[i+(1<<(j-1))][j-1]);Min[i][j]=min(Min[i][j-1],Min[i+(1<<(j-1))][j-1]);}}int query(int l,int r){int k=0;while ((1<<(k+1))<=r-l+1)k++;int tmax=max(Max[l][k],Max[r-(1<<k)+1][k]);int tmin=min(Min[l][k],Min[r-(1<<k)+1][k]);return tmax-tmin;}}form;int main(){scanf("%d%d",&n,&q);form.init(n);for (int i=0;i<n;i++)scanf("%d",&a[i]);form.prepare();while (q--){int from,to;scanf("%d%d",&from,&to);printf("%d\n",form.query(from-1,to-1));}return 0;}

线段树:

#include<cstdio>#include<algorithm>#define maxn 51000#define INF 0x7f7f7f7fusing namespace std;int n,q;struct Segment{int left[3*maxn+10],right[3*maxn+10];int Max[3*maxn+10],Min[3*maxn+10];int tmax,tmin;void build(int no,int l,int r){int mid=(l+r)>>1;left[no]=l;right[no]=r;Max[no]=-INF;Min[no]=INF;if (l+1<r){build(2*no,l,mid);build(2*no+1,mid,r);}}void replace(int no,int l,int data){if (left[no]+1==right[no]){Max[no]=max(Max[no],data);Min[no]=min(Min[no],data);}else{int mid=(left[no]+right[no])>>1;if (l<mid)replace(2*no,l,data);else replace(2*no+1,l,data);Max[no]=max(Max[2*no],Max[2*no+1]);Min[no]=min(Min[2*no],Min[2*no+1]);}}int query_max(int no,int l,int r){if (l<=left[no] && right[no]<=r){return Max[no];}else{int mid=(left[no]+right[no])>>1;int tmp=-INF;if (l<mid)tmp=query_max(2*no,l,r);if (r>mid)tmp=max(tmp,query_max(2*no+1,l,r));return tmp;}}int query_min(int no,int l,int r){if (l<=left[no] && right[no]<=r){return Min[no];}else{int mid=(left[no]+right[no])>>1;int tmp=INF;if (l<mid)tmp=query_min(2*no,l,r);if (r>mid)tmp=min(tmp,query_min(2*no+1,l,r));return tmp;}}}tree;int main(){scanf("%d%d",&n,&q);tree.build(1,0,n);for (int i=0;i<n;i++){int a;scanf("%d",&a);tree.replace(1,i,a);}while (q--){int from,to;scanf("%d%d",&from,&to);printf("%d\n",tree.query_max(1,from-1,to)-tree.query_min(1,from-1,to));}return 0;}


0 0
原创粉丝点击