标签:style blog http color io for 数据 ar 2014
描述
南将军统率着N个士兵,士兵分别编号为1~N,南将军经常爱拿某一段编号内杀敌数最高的人与杀敌数最低的人进行比较,计算出两个人的杀敌数差值,用这种方法一方面能鼓舞杀敌数高的人,另一方面也算是批评杀敌数低的人,起到了很好的效果。
所以,南将军经常问军师小工第i号士兵到第j号士兵中,杀敌数最高的人与杀敌数最低的人之间军功差值是多少。
现在,请你写一个程序,帮小工回答南将军每次的询问吧。
注意,南将军可能询问很多次。
5 2 1 2 6 9 3 1 2 2 4
1 7
这题要采用rmq算法(range max/min query)
之前都没听过这个算法,百度了一下:
参考:
http://blog.csdn.net/liang5630/article/details/7917702
RMQ(Range Minimum/Maximum Query),即区间最值查询,是指这样一个问题:对于长度为n的数列A,回答若干询问RMQ(A,i,j)(i,j<=n),返回数列A中下标在i,j之间的最小/大值。这两个问题是在实际应用中经常遇到的问题,下面介绍一下解决这两种问题的比较高效的算法。当然,该问题也可以用线段树(也叫区间树)解决,算法复杂度为:O(N)~O(logN),这里我们暂不介绍。
1 #include<stdio.h> 2 #include<stdlib.h> 3 #include<math.h> 4 #define maxvalue(a,b) ((a) > (b)) ? (a) : (b) 5 #define minvalue(a,b) ((a) < (b)) ? (a) : (b) 6 int a[100005]; 7 int minsum[100005][20],maxsum[100005][20]; 8 int main() 9 { 10 int N,Q,m,n,i,j,k; 11 scanf("%d%d",&N,&Q); 12 for (i=1; i <= N; i++){ 13 scanf("%d",&a[i]); 14 maxsum[i][0] = a[i]; 15 minsum[i][0] = a[i]; 16 } 17 for (j=1; j < 20; j++) 18 for(i=1; i <= N; i++) 19 { 20 if(i + ( 1<<j )-1 <= N ){ 21 minsum[i][j] = minvalue(minsum[i][j-1],minsum[i+(1<<(j-1))][j-1]); 22 maxsum[i][j] = maxvalue(maxsum[i][j-1],maxsum[i+(1<<(j-1))][j-1]); 23 } 24 } 25 while(Q--){ 26 scanf("%d%d",&m,&n); 27 k =log2( n - m + 1); 28 int s = (maxvalue(maxsum[m][k],maxsum[n-(1<<k)+1][k])) - (minvalue(minsum[m][k],minsum[n-(1<<k)+1][k])); 29 printf("%d\n",s); 30 31 } 32 }
标签:style blog http color io for 数据 ar 2014
原文地址:http://www.cnblogs.com/george-cw/p/3933346.html