士兵杀敌(三)rmq
来源:互联网 发布:零之镇魂曲 知乎 编辑:程序博客网 时间:2024/06/09 21:28
士兵杀敌(三)
- 描述
南将军统率着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
本题中是要求范围最小值,最大值即rmp,在实践中最常用的是tarjan的Sparse-Table算法,预处理时间是O(nlogn),但是查询时间只需要O(1)。
首先是预处理:dp_min[i][j],dp_max[i][j]分别存放数组中从i开始到2^j的一段的最小值最大值。
开始初始化dp_min[i][0],dp_max[i][0]等于a[i];初始条件,dp状态都有了,写出动态方程式:
dp_min[i][j] = min(dp_min[i][j-1],dp_min[i+(1<<(j-1))][j-1]);
dp_max[i][j] = max(dp_max[i][j-1],dp_max[i+(1<<(j-1))][j-1]);
即可利用动态规划求解。
例如: 1 2 6 9 3
在运算时首先运算1 2,2 6,6 9,9 3,两个数中的最小/大值
再分别计算1 2 6 9,2 6 9 3,四个数中的最小/大值查询:在返回语句 :min(dp_min[l][k],dp_min[h-(1<<k)+1][k]);
max(dp_max[l][k],dp_max[h-(1<<k)+1][k]);
中是有交叉的,但是不影响结果的正确性。#include<stdio.h>#include<string.h>#include<math.h>#define max(a,b) a>b?a:b#define min(a,b) a>b?b:a#define cl(arr,val) memset(arr,val,sizeof(arr));int n,m,low,high,a[100005],dp_min[100005][20],dp_max[100005][20];void rmq(){int temp = (int)(log(n)/log(2));for(int j=1;j<=temp;j++)for(int i=0;i<n;i++){if(i+(1<<j)<=n){dp_min[i][j] = min(dp_min[i][j-1],dp_min[i+(1<<(j-1))][j-1]);dp_max[i][j] = max(dp_max[i][j-1],dp_max[i+(1<<(j-1))][j-1]);} }}int rmq_min(int l,int h){int k = (int)(log(h-l+1)/log(2));return min(dp_min[l][k],dp_min[h-(1<<k)+1][k]);}int rmq_max(int l,int h){int k = (int)(log(h-l+1)/log(2));return max(dp_max[l][k],dp_max[h-(1<<k)+1][k]);}int main(){int x,y,min,max;scanf("%d%d",&n,&m);cl(a,0);cl(dp_min,0);cl(dp_max,0);for(int i=0;i<n;i++){scanf("%d",&a[i]);dp_min[i][0]=a[i];dp_max[i][0]=a[i];}rmq();while(m--){scanf("%d%d",&low,&high);min = rmq_min(low-1,high-1);max = rmq_max(low-1,high-1);printf("%d\n",max-min);}return 0;}
- 士兵杀敌(三)rmq
- 【RMQ】士兵杀敌(三)
- 士兵杀敌(三)(RMQ算法)
- NYOJ - 士兵杀敌(三)(RMQ)
- 士兵杀敌(三) RMQ算法
- RMQ问题(士兵杀敌(三))
- NYOJ_119_士兵杀敌(三)(RMQ-ST)
- NYOJ 119 士兵杀敌(三)【RMQ】
- nyoj--119 士兵杀敌(三)(RMQ)
- NYOJ119 士兵杀敌(三)(RMQ算法)
- 【RMQ】nyoj-119 士兵杀敌(三)
- nyoj119 士兵杀敌(三)RMQ算法
- [NYOJ 119] 士兵杀敌(三) (RMQ ST算法)
- NYOJ 119 士兵杀敌(三)(RMQ算法)
- NYOJ 题目119士兵杀敌(三)(RMQ)
- NYOJ 119 士兵杀敌(三)(RMQ)
- NYOJ-119-士兵杀敌(三)(RMQ)
- NYOJ 119 士兵杀敌(三) (RMQ ST算法)
- ios软件名称国际化
- mysql在mac笔记本下解决中文乱码问题 并且 在mac下怎么启动和终止mysql服务
- Ubuntu12.04安装TFTP失败怎么办
- Linux Raw Socket使用总结
- lua_settable
- 士兵杀敌(三)rmq
- poj 2104 K-th Number(线段树)
- C语言extern和static--2014.10.10
- 黑马程序员---------Java面向对象——反射
- Java中的类与对象
- Java基础加强_Eclipse、枚举、反射、注解、泛型、类加载器、动态代理
- spring3国际化 动态语言切换
- Segment公司--整合数据进行分析
- 优化小技巧