nyoj 1185 最大最小值【线段树最大值最小值维护】

最大最小值

时间限制:1000 ms  |  内存限制:65535 KB
难度:2
 
描述
给出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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
#include<stdio.h>
#include<string.h>
#include<algorithm>
#define MAX 10010
using namespace std;
int Min[MAX<<2];
int Max[MAX<<2];
void pushup(int o)
{
    Max[o]=max(Max[o<<1],Max[o<<1|1]);
    Min[o]=min(Min[o<<1],Min[o<<1|1]);
}
void gettree(int o,int l,int r)
{
    int a;
    if(l==r)
    {
        scanf("%d",&a);
        Max[o]=Min[o]=a;
        return ;
    }
    int mid=(l+r)>>1;
    gettree(o<<1,l,mid);
    gettree(o<<1|1,mid+1,r);
    pushup(o);
}
int find1(int o,int l,int r,int L,int R)
{
    if(L<=l&&R>=r)
    {
        return Min[o];
    }
    int mid=(l+r)>>1;
    int ans=MAX;
    if(mid>=R)
        ans=min(find1(o<<1,l,mid,L,R),ans);
    else if(mid<L)
        ans=min(find1(o<<1|1,mid+1,r,L,R),ans);
    else
    {
        ans=min(find1(o<<1,l,mid,L,R),ans);
        ans=min(find1(o<<1|1,mid+1,r,L,R),ans);
    }
    return ans;    
}
int find2(int o,int l,int r,int L,int R)
{
    if(L<=l&&R>=r)
        return Max[o];
    int mid=(l+r)>>1;
    int ans=-100;
    if(R<=mid)
        ans=max(ans,find2(o<<1,l,mid,L,R));
    else if(L>mid)
        ans=max(ans,find2(o<<1|1,mid+1,r,L,R));
    else
    {
        ans=max(ans,find2(o<<1,l,mid,L,R));
        ans=max(ans,find2(o<<1|1,mid+1,r,L,R));
    }  
    return ans; 
}
int main()
{
    int t,n,m,j,i;
    int a,b,c;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d",&n);
        gettree(1,1,n);
        scanf("%d",&m);
        for(i=1;i<=m;i++)
        {
            scanf("%d%d%d",&a,&b,&c);
            if(a==1)
            {
                printf("%d\n",find1(1,1,n,b,c));
            }
            if(a==2)
            {
                printf("%d\n",find2(1,1,n,b,c));
            }
            if(a==3)
            {
                printf("%d\n",find1(1,1,n,b,c)+find2(1,1,n,b,c));
            }
        }
    }
    return 0;
}

  

posted @   非我非非我  阅读(662)  评论(0编辑  收藏  举报
编辑推荐:
· 从二进制到误差:逐行拆解C语言浮点运算中的4008175468544之谜
· .NET制作智能桌面机器人:结合BotSharp智能体框架开发语音交互
· 软件产品开发中常见的10个问题及处理方法
· .NET 原生驾驭 AI 新基建实战系列:向量数据库的应用与畅想
· 从问题排查到源码分析:ActiveMQ消费端频繁日志刷屏的秘密
阅读排行:
· Windows桌面应用自动更新解决方案SharpUpdater5发布
· 我的家庭实验室服务器集群硬件清单
· C# 13 中的新增功能实操
· Supergateway:MCP服务器的远程调试与集成工具
· Vue3封装支持Base64导出的电子签名组件
点击右上角即可分享
微信分享提示