士兵杀敌(三)

时间限制: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
题解:线段树;还可以用RMQ算法,感觉挺复杂,也没看。。。还有宏定义最好大写。。。。。 思路:线段树叶子节点存两个值:最大和最小值
#include <iostream>
#include <iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<algorithm>
#include <stdio.h>
#include <string.h>
#define rep(i , n) for(int i = 0 ; i < (n) ; i++)
using namespace std;
const int N = ;
const int INF=0x3f3f3f3f;
long long ans = , flag = ;
long long a[] , sum1[] , sum2[];
long long max1 = -INF , min1 = INF;
struct Node{
long long l , r , mi , ma ;
}tree[N*]; void build(long long l , long long r , int root)
{
tree[root].l = l , tree[root].r = r ;
if(l == r)
{
scanf("%lld" ,&tree[root].mi);
tree[root].ma = tree[root].mi ;
return ;
}
long long mid = (l + r) >> ;
if(l <= mid)
build(l , mid , root*);
if(r > mid)
build(mid+ , r , root*+);
tree[root].mi = min(tree[root*].mi , tree[root*+].mi);
tree[root].ma = max(tree[root*].ma , tree[root*+].ma);
cout << tree[root].ma << " " << tree[root].mi << endl ;
} void query(long long l , long long r , int root)
{
if(tree[root].l >= l && tree[root].r <= r)
{
cout << tree[root].ma <<" " << tree[root].mi <<endl ;
max1 = max(max1 , tree[root].ma) ;
min1 = min(min1 , tree[root].mi) ;
return ;
}
long long mid = (tree[root].l + tree[root].r) >> ;
if(l <= mid)
query(l , r , root*);
if(r > mid)
query(l , r, root*+);
} int main()
{ int n , q ;
while(~scanf("%d%d" , &n , &q))
{
build( , n , );
for(int i = ; i < q ; i++)
{
long long l , r ;
scanf("%lld%lld" , &l ,&r);
query(l , r , );
cout << max1 - min1 << endl ;
max1 = -INF , min1 = INF ; // 不能赋值为零噢。
}
} return ;
}

RMQ(算法)st表排序

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

#include <iostream>
#include <iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<algorithm>
#include <stdio.h>
#include <math.h>
#include <string.h>
#define rep(i , n) for(int i = 0 ; i < (n) ; i++)
using namespace std;
const int N = ;
const int INF=0x3f3f3f3f;
long long ans = , flag = ;
long long max1 = -INF , min1 = INF;
int a[N] , dpa[N][N] , dpb[N][N];
int n , q ;

void RMQ()
{
for(int j = ; j < ; j++)
{
for(int i = ; i <= n ; i++)
{
if(i + ( << j) - <= n)
{
dpa[i][j] = max(dpa[i][j-] , dpa[i + ( << j - )][j-]);//状态转移方程
dpb[i][j] = min(dpb[i][j-] , dpb[i+ ( << j - )][j-]); } }
}
} int main()
{ while(~scanf("%d%d" , &n , &q))
{
for(int i = ; i <= n ; i++)
{
scanf("%d" , &a[i]);
dpa[i][] = dpb[i][] = a[i];//赋初值
}
RMQ(); for(int i = ; i < q ; i++)
{
long long l , r ;
scanf("%lld%lld" , &l ,&r);
int k = (int)(log(r - l + ) / log(2.0)) ;
int max1 = max(dpa[l][k] , dpa[r-( << k) + ][k]);//查表
int min1 = min(dpb[l][k] , dpb[r -( << k) + ][k]);
printf("%d\n" , max1 - min1);
}
} return ;
}

线段树(two value)与树状数组(RMQ算法st表)的更多相关文章

  1. BZOJ_1012_[JSOI2008]_最大数maxnumber_(线段树/树状数组+RMQ)

    描述 http://www.lydsy.com/JudgeOnline/problem.php?id=1012 两种操作: 1.求序列末尾n个数中的最大值. 2.在序列末尾插入一个数. 分析 线段树求 ...

  2. 【BZOJ】1012: [JSOI2008]最大数maxnumber(树状数组+rmq)

    http://www.lydsy.com/JudgeOnline/problem.php?id=1012 树状数组原来我只懂得sum和add的操作,今天才知道可以有求区间最值的操作,我学习了一下写了个 ...

  3. Codeforces 803G Periodic RMQ Problem ST表+动态开节点线段树

    思路: (我也不知道这是不是正解) ST表预处理出来原数列的两点之间的min 再搞一个动态开节点线段树 节点记录ans 和标记 lazy=-1 当前节点的ans可用  lazy=0 没被覆盖过 els ...

  4. 线段树:CDOJ1591-An easy problem A (RMQ算法和最简单的线段树模板)

    An easy problem A Time Limit: 1000/1000MS (Java/Others) Memory Limit: 65535/65535KB (Java/Others) Pr ...

  5. BZOJ4199 [Noi2015]品酒大会 【后缀数组 + 单调栈 + ST表】

    题目 一年一度的"幻影阁夏日品酒大会"隆重开幕了.大会包含品尝和趣味挑战两个环节,分别向优胜者颁发"首席品 酒家"和"首席猎手"两个奖项,吸 ...

  6. [BZOJ3277/BZOJ3473] 串 - 后缀数组,二分,双指针,ST表,均摊分析

    [BZOJ3277] 串 Description 现在给定你n个字符串,询问每个字符串有多少子串(不包括空串)是所有n个字符串中至少k个字符串的子串(注意包括本身). Solution 首先将所有串连 ...

  7. bzoj3277 串 (后缀数组+二分答案+ST表)

    常见操作:先把所有串都连到一起,但中间加上一个特殊的符号(不能在原串中/出现过)作为分割 由于全部的子串就等于所有后缀的所有前缀,那我们对于每一个后缀,去求一个最长的前缀,来满足这个前缀在至少K个原串 ...

  8. BZOJ3879:SvT(后缀数组,单调栈,ST表)

    Description (我并不想告诉你题目名字是什么鬼) 有一个长度为n的仅包含小写字母的字符串S,下标范围为[1,n]. 现在有若干组询问,对于每一个询问,我们给出若干个后缀(以其在S中出现的起始 ...

  9. POJ 3321 Apple Tree 【树状数组+建树】

    题目链接:http://poj.org/problem?id=3321 Apple Tree Time Limit: 2000MS Memory Limit: 65536K Total Submiss ...

随机推荐

  1. 案例 element 表单名两端对齐

    >>> .el-form-item label:after { content: ""; display: inline-block; width: 100%; ...

  2. FCKeditor用在JSP中的几点注意事项

    转自:https://blog.csdn.net/asinzy/article/details/3854127 本篇文章主要介绍了"FCKeditor用在JSP中的几点注意事项", ...

  3. Docker之安装缺省指令

    Docker 中有些指令不存在,需要额外的安装,这里做下安装记录. 更新软件源中的所有软件列表 apt-get update 安装 ifconfig apt install net-tools 安装 ...

  4. 【串线篇】spring boot日志使用

    一.默认配置 1.SpringBoot默认帮我们配置好了日志: //记录器 Logger logger = LoggerFactory.getLogger(getClass()); @Test pub ...

  5. spring mvc 和spring boot 中注解的使用

    1 spring mvc和spring boot之间的关系 spring boot包含spring mvc.所以,spring mvc的注解在spring boot总都是可以用的吗? spring b ...

  6. LeetCode--041--缺失的第一个整数(java)

    给定一个未排序的整数数组,找出其中没有出现的最小的正整数. 示例 1: 输入: [1,2,0] 输出: 3 示例 2: 输入: [3,4,-1,1] 输出: 2 示例 3: 输入: [7,8,9,11 ...

  7. Docker Swarm学习教程【转载】

    Swarm介绍 Swarm是Docker公司在2014年12月初发布的一套较为简单的工具,用来管理Docker集群,它将一群Docker宿主机变成一个单一的,虚拟的主机.Swarm使用标准的Docke ...

  8. 又联考了一场,感觉自己好菜啊,T2推出了公式但是不会逆元QAQ,难受啊!!!不过都确实是一道逆元的好题撒!

    简单的玄学(random) 题目描述: 样例输入: 样例1: 3 2 样例2: 1 3 样例3: 4 3 样例输出: 样例1: 1 8 样例2: 1 1 样例3: 23 128 提示: 时间限制:10 ...

  9. 【CF1257E】The Contest【线段树】

    题意:给定三个序列abc,问最少操作几次使得满足a<b<c 题解:将三个序列合并起来,设cnt[i][1/2/3]表示前i个数有几个是来自序列1/2/3的. 枚举第一个序列要到i,此时对于 ...

  10. PHP实现多服务器SESSION共享

    为什么要session共享? 现在稍微大一点的网站基本上都有好几个子域名,比如www.feiniu.com, search.feiniu.com, member.feiniu.com,这些网站如果需要 ...