最大最小值(线段树基础版)

最大最小值

时间限制:1000 ms  |  内存限制:65535 KB

描述

给出N个整数,执行M次询问。

对于每次询问,首先输入三个整数C、L、R:

如果C等于1,输出第L个数到第R个数之间的最小值;

如果C等于2,输出第L个数到第R个数之间的最大值;

如果C等于3,输出第L个数到第R个数之间的最小值与最大值的和。

(包括第L个数和第R个数)。

输入
首先输入一个整数T(T≤100),表示有T组数据。

对于每组数据,先输入一个整数N(1≤N≤10000),表示有N个整数;

接下来一行有N个整数a(1≤a≤10000);

然后输入一个整数M,表示有M次询问;

接下来有M行(1≤M≤10000),每行有3个整数C、L、R(1≤C≤3,1≤L≤R≤N)。

输出
按照题意描述输出。每个输出占一行。
样例输入
2
4
1 3 2 4
2
1 1 4
2 2 3
5
1 2 3 4 5
1
3 1 5
样例输出
1
3
6
代码:
//区间线段树
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <math.h>
#include <algorithm>
using namespace std;

const int maxn= 10005;
int a[maxn];
int Min[maxn][20], Max[maxn][20];
int N; //元素个数
int read()
{
    int res = 0, flag = 0;
    char ch;
    if((ch = getchar()) == '-') flag = 1;
    else if(ch >= '0' && ch <= '9') res = ch - '0';
    while((ch = getchar()) >= '0' && ch <= '9')
        res = res * 10 + (ch - '0');
    return flag ? -res : res;
}
int RMQ_Init()    // 预处理出最大值和最小值
{
    for(int i = 1; i <= N; i++)
        Min[i][0] = Max[i][0] = a[i];
    for(int j = 1; (1<<j) <= N; j++)
    {
        for(int i = 1; i + (1<<j) - 1 <= N; i++)
        {
            Min[i][j] = min(Min[i][j-1], Min[i + (1<<(j-1))][j-1]);
            Max[i][j] = max(Max[i][j-1], Max[i + (1<<(j-1))][j-1]);
        }
    }
}

int RMQ_Min(int L, int R)   // 查询[L,R]之间的最小值
{
    int k = 0;
    while((1<<(k+1)) <= R - L + 1) k++;
    return min(Min[L][k], Min[R - (1<<k) + 1][k]);
}

int RMQ_Max(int L, int R)   // 查询[L,R]之间的最大值
{
    int k = 0;
    while((1<<(k+1)) <= R - L + 1) k++;
    return max(Max[L][k], Max[R - (1<<k) + 1][k]);
}

int main()
{
    //freopen("1.txt","r",stdin);
    //freopen("2.txt","w",stdout);
    int T, M;
    int  C, L, R;
    T=read();
    while(T--)
    {
        N=read();
        for(int i = 1; i <= N; i++)  a[i]=read();
        RMQ_Init();
        M=read();
        while(M--)
        {
            C=read();
            L=read();
            R=read();
            if(C == 1) printf("%d\n", RMQ_Min(L, R));
            else if(C == 2) printf("%d\n", RMQ_Max(L, R));
            else printf("%d\n", RMQ_Max(L, R) + RMQ_Min(L, R));
        }
    }
    return 0;
}
时间: 2024-10-08 02:25:11

最大最小值(线段树基础版)的相关文章

SegmentTree-Complete 线段树完全版

线段树完全版关键词:延迟加载.懒标记Lazy Tag 单点更新的情况比较简单.请看 线段树基础版 下面说说区间更新的情况. 场景是这样的,还是刚刚的数,求区间的和. #define lson rt<<1 #define rson rt<<1|1 #define len (r-l+1) //(l,r)区间的长度 这次是区间更新,我们要用到区间的长度 建树 build和pushUp不变.我们把树建立好打印一下: [1]:36 [2]:26 [3]:10 [4]:15 [5]:11 [6

线段树基础知识----(基础数据结构)--(一)

1.定义 引入:为什么要使用线段树而不用数组模拟呢? answer:因为有些题用数组来做就要超时,用线段树的O(log(n))的时间复杂度刚好可以求解 毫无疑问线段树是一种数据结构,但是它实际是一个类似树状的链表结构(个人认为) ///还是要正经一点(照搬教科书)----------- / ////////////////////////////////////////////////////////////////////// 线段树定义:线段树是一种二叉搜索树,与区间树相似,它将一个区间划分

线段树 基础单点更新 敌兵布阵

题:敌兵布阵 标准线段树模板代码: #include<cstdio> #include<cstring> const int maxn = 500000 + 10; struct Node{ int left, right, count; }node[maxn]; int a[maxn]; /*********************************** ***************建树**************** ************i是区间序号********

区间最小值 线段树 (2015年 JXNU_ACS 算法组暑假第一次周赛)

区间最小值 Time Limit : 3000/1000ms (Java/Other)   Memory Limit : 65535/32768K (Java/Other) Total Submission(s) : 12   Accepted Submission(s) : 5 Font: Times New Roman | Verdana | Georgia Font Size: ← → Problem Description 给定一个数字序列,查询随意给定区间内数字的最小值. Input

线段树基础

关于线段树的原理学习,可以参看杨弋大牛的论文<线段树>以及刘汝佳老师的<算法竞赛入门经典(训练指南)>,代码风格学习hzwer或者notonlysuccess均可. 一.单点更新 最基础的线段树 题目:codevs1080 链接:http://codevs.cn/problem/1080/ 分析:最简单的线段树,单点更新,区间求和 1 #include<iostream> 2 #include<cstdio> 3 using namespace std; 4

[您有新的未分配科技点]可,可,可持久化!?------可持久化线段树普及版讲解

最近跑来打数据结构,于是我决定搞一发可持久化,然后发现--一发不可收啊-- 对于可持久化数据结构,其最大的特征是"历史版本查询",即可以回到某一次修改之前的状态,并继续操作:而这种"历史版本查询"会衍生出其他一些强大的操作. 今天,我们主要讲解可持久化线段树.其实,它的另外一个名字"主席树"似乎更加为人所知(主席%%%). 主席树与普通的线段树相比,多出来的操作是在修改时复制修改的一条链,这个操作的过程大概长下面这样. 至于为什么要这样做-- 对

杭电 HDU ACM 2795 Billboard(线段树伪装版)

Billboard Time Limit: 20000/8000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 14144    Accepted Submission(s): 6058 Problem Description At the entrance to the university, there is a huge rectangular billboard of

HDU 1754--I Hate It(线段树基础)

I Hate It Time Limit: 9000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 44820    Accepted Submission(s): 17591 Problem Description 很多学校流行一种比较的习惯.老师们很喜欢询问,从某某到某某当中,分数最高的是多少. 这让很多学生很反感.不管你喜不喜欢,现在需要你做的是,就是按照老师的

tyvj 1038 忠诚 区间最小值 线段树或者rmq

P1038 忠诚 时间: 1000ms / 空间: 131072KiB / Java类名: Main 描述 老管家是一个聪明能干的人.他为财主工作了整整10年,财主为了让自已账目更加清楚.要求管家每天记k次账,由于管家聪明能干,因而管家总是让财主十分满意.但是由于一些人的挑拨,财主还是对管家产生了怀疑.于是他决定用一种特别的方法来判断管家的忠诚,他把每次的账目按1,2,3…编号,然后不定时的问管家问题,问题是这样的:在a到b号账中最少的一笔是多少?为了让管家没时间作假他总是一次问多个问题. 输入