题意:给出n个数,a1,a2,a3,---,an,再给出q次询问区间al到ar之间的最大值和最小值的差
学习线段树的第一道题目 学习的这一篇
http://www.cnblogs.com/kuangbin/archive/2011/08/14/2137862.html
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include <cmath> 5 #include<stack> 6 #include<vector> 7 #include<map> 8 #include<set> 9 #include<queue> 10 #include<algorithm> 11 using namespace std; 12 13 typedef long long LL; 14 const int INF = (1<<30)-1; 15 const int mod=1000000007; 16 const int maxn=1000005; 17 18 int a[maxn]; 19 int nmax,nmin; 20 21 struct node{ 22 int l,r;//记录区间的左右端点 23 int nmax,nmin;//记录区间的最大值,最小值 24 }; 25 26 node tree[4*maxn]; 27 28 void build_tree(int i,int l,int r){//建树 29 tree[i].l=l; 30 tree[i].r=r; 31 if(l==r){ 32 tree[i].nmin=tree[i].nmax=a[l]; 33 return; 34 } 35 int mid=(l+r)/2; 36 build_tree(2*i,l,mid); 37 build_tree(2*i+1,mid+1,r); 38 tree[i].nmin=min(tree[2*i].nmin,tree[2*i+1].nmin); 39 tree[i].nmax=max(tree[2*i].nmax,tree[2*i+1].nmax); 40 } 41 42 void query(int i,int l,int r){//查询 43 if(tree[i].nmin>=nmin&&tree[i].nmax<=nmax) return; 44 if(tree[i].l==l&&tree[i].r==r){ 45 nmin = min(tree[i].nmin,nmin); 46 nmax = max(tree[i].nmax,nmax); 47 return; 48 } 49 int mid=(tree[i].l+tree[i].r)/2; 50 if(r<=mid) query(2*i,l,r); 51 else if(l>mid) query(2*i+1,l,r); 52 else{ 53 query(2*i,l,mid); 54 query(2*i+1,mid+1,r); 55 } 56 } 57 58 int main(){ 59 int n,q; 60 while(scanf("%d %d",&n,&q)!=EOF){ 61 for(int i=1;i<=n;i++) scanf("%d",&a[i]); 62 build_tree(1,1,n); 63 64 while(q--){ 65 nmin=INF;nmax=-INF; 66 int l,r; 67 scanf("%d %d",&l,&r); 68 query(1,l,r); 69 printf("%d\n",nmax-nmin); 70 } 71 } 72 return 0; 73 }
另外这道题用cin会超时
时间: 2024-10-13 14:41:24