RMQ算法求最大最小差值

    技术2022-05-20  41

    士兵杀敌(三)

    时间限制: 2000 ms  |  内存限制: 65535 KB 难度: 5 描述

    南将军统率着N个士兵,士兵分别编号为1~N,南将军经常爱拿某一段编号内杀敌数最高的人与杀敌数最低的人进行比较,计算出两个人的杀敌数差值,用这种方法一方面能鼓舞杀敌数高的人,另一方面也算是批评杀敌数低的人,起到了很好的效果。

    所以,南将军经常问军师小工第i号士兵到第j号士兵中,杀敌数最高的人与杀敌数最低的人之间军功差值是多少。

    现在,请你写一个程序,帮小工回答南将军每次的询问吧。

    注意,南将军可能询问很多次。

    输入 只有一组测试数据 第一行是两个整数N,Q,其中N表示士兵的总数。Q表示南将军询问的次数。(1<N<=100000,1<Q<=1000000) 随后的一行有N个整数Vi(0<=Vi<100000000),分别表示每个人的杀敌数。 再之后的Q行,每行有两个正正数m,n,表示南将军询问的是第m号士兵到第n号士兵。 输出 对于每次询问,输出第m号士兵到第n号士兵之间所有士兵杀敌数的最大值与最小值的差。 样例输入 5 2 1 2 6 9 3 1 2 2 4 样例输出 1 7

     

    #include <stdio.h> #include <stdlib.h> #include <math.h> #include <string.h> #include <iostream> using namespace std; int num[100005]; int RMQMatrixA[100005][20]; int RMQMatrixB[100005][20]; int snum,sask; int max(int a,int b) { return a>b?a:b; } int min(int a,int b) { return a<b?a:b; } int GetMax(int a,int b,int k) { return max(RMQMatrixA[a][k],RMQMatrixA[b -(1<<k) + 1][k]); } int GetMin(int a,int b,int k) { return min(RMQMatrixB[a][k],RMQMatrixB[b -(1<<k) + 1][k]); } int main() { int i,j; //freopen("E://input.txt","r",stdin); scanf("%d%d",&snum,&sask); for(i = 1; i <= snum; i++) { scanf("%d",&num[i]); RMQMatrixA[i][0] = num[i]; RMQMatrixB[i][0] = num[i]; } for(j = 1; j < log((double)(snum+1))/log(2.0); j++) { for(i = 1; (i + (1 << j) - 1) <= snum; i++) { RMQMatrixA[i][j] = max(RMQMatrixA[i][j-1],RMQMatrixA[i + (1 << (j-1))][j - 1]); } } for(j = 1; j < log((double)(snum+1))/log(2.0);j++) { for(i = 1; (i + (1 << j) - 1)<= snum; i++) { RMQMatrixB[i][j] = min(RMQMatrixB[i][j-1],RMQMatrixB[i + (1<<(j-1))][j - 1]); } } while(sask--) { int r1,r2,k; scanf("%d%d",&r1,&r2); //求得一个k,使2^k与[x,y]内的数的个数最接近, //以保证二分的两个区间包含所有区间内所有数 k = (int)(log((double)(r2 - r1 + 1))/log(2.0)); printf("%d/n",GetMax(r1,r2,k)-GetMin(r1,r2,k)); } return 0; }  


    最新回复(0)