• 1270. 数列区间最大值


    输入一串数字,给你 M 个询问,每次询问就给你两个数字 X,Y,要求你说出 X 到 Y 这段区间内的最大数。
    输入格式
    第一行两个整数 N,M 表示数字的个数和要询问的次数;
    接下来一行为 N 个数;
    接下来 M 行,每行都有两个整数 X,Y。
    输出格式
    输出共 M 行,每行输出一个数。
    数据范围
    (1≤N≤10^{5},\1≤M≤10^{6},\1≤X≤Y≤N,)
    数列中的数字均不超过(2^{31}−1)

    不同格式化输入输出这题别想过了。。。另外用线段树写起来很方便,但是树状数组写起来求(x, y)内的最大值比较麻烦。

    树状数组

    #include<iostream>
    #include<climits>
    #include<cstdio>
    
    using namespace std;
    
    const int N = 100010;
    
    int tr[N], w[N];
    int n, m;
    
    int lowbit(int x){
        return x & -x;
    }
    
    int query(int x, int y){
        int res = INT_MIN;
        
        while(y - lowbit(y) >= x){
            res = max(res, tr[y]);
            y -= lowbit(y);
        }
        
        while(y >= x){
            res = max(res, w[y]);
            
            if(y - lowbit(y) < x) -- y;
            else{
                res = max(res, tr[y]);
                y -= lowbit(y);
            }
        }
    
        return res;
    }
    
    void add(int x, int v){
        for(int i = x; i <= n; i += lowbit(i)) tr[i] = max(tr[i], v); 
    }
    
    int main(){
        scanf("%d%d", &n, &m);
        
        for(int i = 1; i <= n; i ++){
            scanf("%d", &w[i]);
            add(i, w[i]);
        }
        
        while(m --){
            int x, y;
            scanf("%d%d", &x, &y);
            
            printf("%d
    ", query(x, y));
        }
        
        
        return 0;
    }
    

    线段树

    #include<iostream>
    #include<climits>
    
    using namespace std;
    
    const int N = 100010;
    
    struct Node{
        int l, r;
        int maxv;
    }tr[N * 4];
    
    int n, m;
    int w[N];
    
    void pushup(int u){
        tr[u].maxv = max(tr[u << 1].maxv, tr[u << 1 | 1].maxv); 
    }
    
    void build(int u, int l, int r){
        if(l == r) tr[u] = {l, r, w[l]};
        else{
            tr[u] = {l, r};
            int mid = l + r >> 1;
            build(u << 1, l, mid);
            build(u << 1 | 1, mid + 1, r);
            pushup(u);
        }
    }
    
    int query(int u, int l, int r){
        if(l <= tr[u].l && r >= tr[u].r) return tr[u].maxv;
        int mid = tr[u].l + tr[u].r >> 1;
        int maxv = INT_MIN;
        if(l <= mid) maxv = query(u << 1, l, r);
        if(r > mid) maxv = max(maxv, query(u << 1 | 1, l, r));
        return maxv;
    }
    
    int main(){
        scanf("%d%d", &n, &m);
        
        for(int i = 1; i <= n; i ++) scanf("%d", &w[i]);
        
        build(1, 1, n);
        
        while(m --){
            int x, y;
            
            scanf("%d%d", &x, &y);
            
            printf("%d
    ", query(1, x, y));
        }
        
        return 0;
    }
    
  • 相关阅读:
    __weak
    c++界面设计皮肤工具
    执行游戏时出现0xc000007b错误的解决方法
    2.4.1-Java语言基础(常量)
    句法模式识别(一)-串文法
    一步一步写算法(之hash表)
    LaTeX新人教程,30分钟从全然陌生到基本入门
    初次当面试官的经历和感触
    Android入门第八篇之GridView(九宫图)
    Android-Cannot merge new index 66195 into a non-jumbo instruction的解决的方法
  • 原文地址:https://www.cnblogs.com/tomori/p/13723494.html
Copyright © 2020-2023  润新知