RMQ(区间最值查询) NYOJ 119

来源:互联网 发布:linux查看文件编码格式 编辑:程序博客网 时间:2024/06/04 17:40

士兵杀敌(三)
时间限制:2000 ms | 内存限制:65535 KB
难度:5
描述
南将军统率着N个士兵,士兵分别编号为1~N,南将军经常爱拿某一段编号内杀敌数最高的人与杀敌数最低的人进行比较,计算出两个人的杀敌数差值,用这种方法一方面能鼓舞杀敌数高的人,另一方面也算是批评杀敌数低的人,起到了很好的效果。

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

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

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

输入
只有一组测试数据
第一行是两个整数N,Q,其中N表示士兵的总数。Q表示南将军询问的次数。(1

#include<cstdio>  #include<algorithm>  #include<cmath>  using namespace std;  const int N = 100010; //数组范围int maxsum[20][N], minsum[20][N];   void RMQ(int num) //预处理->O(nlogn)  {      for(int i = 1; i != 20; ++i)          for(int j = 1; j <= num; ++j)              if(j + (1 << i) - 1 <= num)              {                  maxsum[i][j] = max(maxsum[i - 1][j], maxsum[i - 1][j + (1 << i >> 1)]); //优化2                  minsum[i][j] = min(minsum[i - 1][j], minsum[i - 1][j + (1 << i >> 1)]);              }  }  int main()  {      int num, query;      int src, des;      scanf("%d %d", &num, &query);          for(int i = 1; i <= num; ++i) //输入信息处理          {              scanf("%d", &maxsum[0][i]);              minsum[0][i] = maxsum[0][i];          }          RMQ(num);  //数组大小num        while(query--) //O(1)查询          {              scanf("%d %d", &src, &des);//区间左右值              int k = (int)(log(des - src + 1.0) / log(2.0));              int maxres = max(maxsum[k][src], maxsum[k][des - (1 << k) + 1]);              int minres = min(minsum[k][src], minsum[k][des - (1 << k) + 1]);              printf("%d\n", maxres - minres);          }      return 0;  }  
0 0
原创粉丝点击