NYOJ-119 士兵杀敌(三)【RMQ算法】

原创 2012年03月27日 21:14:39

题目链接:http://acm.nyist.net/JudgeOnline/problem.php?pid=119

解题思路:

RMQ算法。

不会的可以去看看我总结的RMQ算法。

http://blog.csdn.net/niushuai666/article/details/6624672


代码如下:

#include<cstdio>
#include<algorithm>
#include<cmath>
using namespace std;

const int N = 100010;
int maxsum[N][20], minsum[N][20];

void RMQ(int num) //预处理->O(nlogn)
{
	for(int j = 1; j < 20; ++j)
		for(int i = 1; i <= num; ++i)
			if(i + (1 << j) - 1 <= num)
			{
				maxsum[i][j] = max(maxsum[i][j - 1], maxsum[i + (1 << (j - 1))][j - 1]);
				minsum[i][j] = min(minsum[i][j - 1], minsum[i + (1 << (j - 1))][j - 1]);
			}
}

int main()
{
	int num, query;
	int src, des;
	scanf("%d %d", &num, &query);
		for(int i = 1; i <= num; ++i) //输入信息处理
		{
			scanf("%d", &maxsum[i][0]);
			minsum[i][0] = maxsum[i][0];
		}
		RMQ(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[src][k], maxsum[des - (1 << k) + 1][k]);
			int minres = min(minsum[src][k], minsum[des - (1 << k) + 1][k]);
			printf("%d\n", maxres - minres);
		}
	return 0;
}

代码优化后:

#include<cstdio>
#include<algorithm>
#include<cmath>
using namespace std;

const int N = 100010;
int maxsum[20][N], minsum[20][N]; //优化1

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);
		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;
}

优化1:数组由F[N][20]变为F[20][N];

因为数组的地址为a + i + j,对应上面数组,我们需要先循环N的部分,所以

如果是第一种,我们计算时因为i不断变化,我们就需要计算a + i + j

如果是第二种,我们计算时a + i不变,只需要改变j

优化2:

位运算

相关文章推荐

士兵杀敌(一)(nyoj_108)

士兵杀敌(一) 时间限制:1000 ms  |  内存限制:65535 KB 难度:3 描述 南将军手下有N个士兵,分别编号1到N,这些士兵的杀敌数都是已知的。 小工是南将军手下的军师,...

nyoj 228 士兵杀敌(五)

很巧妙的一道题, 一看时间限制线段树也会TLE,就要换种思路了,因为是先更新,更新完毕之后才会询问,所以可以在更新的时候直接将区间最小值对应的数组中加上所需要加的值,区间最大值+1对应的数组减去所需...
  • AcmLzq
  • AcmLzq
  • 2016年05月11日 18:50
  • 404

士兵杀敌(三)

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

【南理工oj】119 - 士兵杀敌(三)(线段树,坑)

士兵杀敌(三) 时间限制:2000 ms  |  内存限制:65535 KB 难度:5 描述 南将军统率着N个士兵,士兵分别编号为1~N,南将军经常爱拿某一段编号内杀敌数最高的人与杀敌数最...
  • wyg1997
  • wyg1997
  • 2016年04月26日 16:17
  • 411

nyoj119 士兵杀敌(三) (线段树,两个value)

士兵杀敌(三) 时间限制:2000 ms  |  内存限制:65535 KB 难度:5 描述 南将军统率着N个士兵,士兵分别编号为1~N,南将军经常爱拿某一段编号内杀敌数最高的人与杀敌数最...

【51Nod1244】莫比乌斯函数之和

Description莫比乌斯函数,由德国数学家和天文学家莫比乌斯提出。梅滕斯(Mertens)首先使用μ(n)(miu(n))作为莫比乌斯函数的记号。具体定义如下: 如果一个数包含平方因子,那么m...

poj 3667 Hotel(线段树,区间合并)

HH神总结的线段树专辑:https://wenku.baidu.com/view/71fc1659ba1aa8114431d97b.html 里面的例题,看懂代码后。基本也就把代码背下来了。。。 ...

NYOJ119 士兵杀敌(三)(RMQ算法)

题目: 士兵杀敌(三) 时间限制:2000 ms  |  内存限制:65535 KB 难度:5 描述 南将军统率着N个士兵,士兵分别编号为1~N,南将军经...

【解题报告】NYOJ 119 士兵杀敌(三)--RMQ算法详解

RMQ问题 题目连接:http://acm.nyist.net/JudgeOnline/problem.php?pid=119------  士兵杀敌(三) 大意就是,有一个数列 {a1,a2,a...

nyoj119 士兵杀敌(三)RMQ算法

士兵杀敌(三) 时间限制:2000 ms  |  内存限制:65535 KB 难度:5 描述 南将军统率着N个士兵,士兵分别编号为1~N,南将军经常爱拿某一段编号内杀敌数最高的人与杀敌数最...
  • BBHHTT
  • BBHHTT
  • 2017年08月09日 08:03
  • 69
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:NYOJ-119 士兵杀敌(三)【RMQ算法】
举报原因:
原因补充:

(最多只允许输入30个字)