Time Limit: 5000MS | Memory Limit: 65536K | |
Total Submissions: 23931 | Accepted: 11122 | |
Case Time Limit: 2000MS |
Description
For the daily milking, Farmer John's N cows (1 ≤ N ≤ 50,000) always line up in the same order. One day Farmer John decides to organize a game of Ultimate Frisbee with some of the cows. To keep things simple, he will take a contiguous range of cows from the milking lineup to play the game. However, for all the cows to have fun they should not differ too much in height.
Farmer John has made a list of Q (1 ≤ Q ≤ 200,000) potential groups of cows and their heights (1 ≤ height ≤ 1,000,000). For each group, he wants your help to determine the difference in height between the shortest and the tallest cow in the group.
Input
Lines 2.. N+1: Line i+1 contains a single integer that is the height of cow i
Lines N+2.. N+ Q+1: Two integers A and B (1 ≤ A ≤ B ≤ N), representing the range of cows from A to B inclusive.
Output
Sample Input
6 3 1 7 3 4 2 5 1 5 4 6 2 2
Sample Output
6 3 0
1 /* 功能Function Description: POJ-3264 2 开发环境Environment: DEV C++ 4.9.9.1 3 技术特点Technique: 4 版本Version: 5 作者Author: 可笑痴狂 6 日期Date: 20120815 7 备注Notes: ------RMQ算法(O(1)的时间复杂度查询区间最值) 8 题意: 9 查询区间最大值与最小值之差 10 */ 11 12 /* 13 //代码一:-----RMQ 14 #include<stdio.h> 15 #include<math.h> 16 #define MAX_N 50000+10 17 #define MAX_L 16 //2^16>50000 18 19 //定义存储的都是下标 20 int maxN[MAX_N][MAX_L]; //maxN[i][j]存储的是从编号i开始的连续2^j个数中最大值的下标 21 int minN[MAX_N][MAX_L]; //minN[i][j]存储的是从编号i开始的连续2^j个数中最小值的下标 22 int h[MAX_N]; 23 24 int max(int i,int j) 25 { 26 return h[i]>h[j]?i:j; 27 } 28 29 int min(int i,int j) 30 { 31 return h[i]<h[j]?i:j; 32 } 33 34 void preST(int n) //ST的预处理 35 { 36 int i,j; 37 for(i=0;i<n;++i) //初始时候 h[minN[i][0]]=h[maxN[i][0]]=h[i] 38 minN[i][0]=maxN[i][0]=i; 39 for(j=1;(1<<j)<=n;++j) //dp 40 { 41 for(i=0;i+(1<<j)-1<n;++i) 42 { 43 maxN[i][j]=max(maxN[i][j-1],maxN[i+(1<<(j-1))][j-1]); 44 minN[i][j]=min(minN[i][j-1],minN[i+(1<<(j-1))][j-1]); 45 } 46 } 47 } 48 49 int ST(int a,int b,int flag) 50 { 51 int pow; 52 --a; 53 --b; 54 for(pow=1;(1<<pow)<b-a+1;++pow); 55 --pow; 56 //pow=(int)log(b-a+1)/log(2); //直接计算pow但是poj不支持 (pow是使2^pow<b-a+1成立的最大值,只有这样才能把a到b拆成两段而完全覆盖) 57 if(flag) //返回最大值 58 return h[max(maxN[a][pow],maxN[b-(1<<pow)+1][pow])]; //因为前后两段有重叠,所以注意是从后边向前计算边界 59 else //返回最小值 60 return h[min(minN[a][pow],minN[b-(1<<pow)+1][pow])]; 61 } 62 63 int main() 64 { 65 int n,m,a,b,i; 66 while(scanf("%d%d",&n,&m)!=EOF) 67 { 68 for(i=0;i<n;++i) 69 scanf("%d",&h[i]); 70 preST(n); 71 for(i=0;i<m;++i) 72 { 73 scanf("%d%d",&a,&b); 74 printf("%d\n",ST(a,b,1)-ST(a,b,0)); 75 } 76 } 77 return 0; 78 } 79 */ 80 81 //代码二:-----------线段树 82 #include<stdio.h> 83 #include<stdlib.h> 84 #define MAX 50000 85 int ansmin,ansmax; 86 87 struct node 88 { 89 int max; 90 int min; 91 int lc; 92 int rc; 93 }tree[MAX*3]; 94 95 void build(int l,int r,int T) 96 { 97 int mid=(l+r)>>1; 98 tree[T].lc=l; 99 tree[T].rc=r; 100 tree[T].min=0x3fffffff; 101 tree[T].max=-1; 102 if(l==r) 103 return; 104 else 105 { 106 build(l,mid,T<<1); 107 build(mid+1,r,(T<<1)|1); 108 } 109 } 110 111 void insert(int num,int k,int T) 112 { 113 int mid=(tree[T].lc+tree[T].rc)>>1; 114 if(num<tree[T].lc||num>tree[T].rc) 115 return; 116 if(tree[T].max<k) 117 tree[T].max=k; 118 if(tree[T].min>k) 119 tree[T].min=k; 120 if(tree[T].lc==tree[T].rc) 121 return; 122 if(num<=mid) 123 insert(num,k,T<<1); 124 else 125 insert(num,k,(T<<1)|1); 126 } 127 128 void qurry(int s,int t,int T) 129 { 130 int mid=(tree[T].lc+tree[T].rc)>>1; 131 if(tree[T].min>ansmin&&tree[T].max<ansmax) //剪枝 132 return; 133 if(tree[T].lc==s&&tree[T].rc==t) 134 { 135 if(ansmin>tree[T].min) //这里要用if语句判断一下,否则在分区间寻找的时候不能综合考虑两个区间的最值 136 ansmin=tree[T].min; 137 if(ansmax<tree[T].max) 138 ansmax=tree[T].max; 139 return; 140 } 141 if(t<=mid) 142 qurry(s,t,T<<1); 143 else if(s>mid) 144 qurry(s,t,(T<<1)|1); 145 else 146 { 147 qurry(s,mid,T<<1); 148 qurry(mid+1,t,(T<<1)|1); 149 } 150 } 151 152 int main() 153 { 154 int n,m,i,a,b,t; 155 while(scanf("%d%d",&n,&m)!=EOF) 156 { 157 build(1,n,1); 158 for(i=1;i<=n;++i) 159 { 160 scanf("%d",&t); 161 insert(i,t,1); 162 } 163 for(i=0;i<m;++i) 164 { 165 ansmin=0x3fffffff; 166 ansmax=-1; 167 scanf("%d%d",&a,&b); 168 qurry(a,b,1); 169 printf("%d\n",ansmax-ansmin); 170 } 171 } 172 return 0; 173 }