• 【题解】Acwing 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
    

    输入样例:

    10 2
    3 2 4 5 6 8 1 2 9 7
    1 4
    3 8
    

    输出样例:

    5
    8
    

    思路分析:

    我就把它当作线段树的练习题了。

    就是求区间最大值,所以我们开个结构体存下它的区间、区间的最大值就好了。

    代码展示:

    #include <iostream>
    #include <cstdio>
    #include <cmath>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    typedef long long ll; typedef unsigned long long ull;
    struct Node {int l, r, dat;};
    
    const int N = 5e5 + 10;
    int n, m, op, x, y, v, a[N];
    Node t[N << 2];
    
    inline void build(int l, int r, int pos) {
    	t[pos].l = l, t[pos].r = r;
    	if(l == r) {t[pos].dat = a[l]; return;} // 找到叶节点了,叶结点最大值为自己
    	int mid = l+r >> 1;
    	build(l, mid, pos << 1), build(mid + 1, r, pos<<1 | 1); // 往下找叶结点
    	t[pos].dat = max(t[pos << 1].dat, t[pos<<1 | 1].dat); // 子节点的最大值
    }
    inline void change(int x, int v, int pos) {
    	if(t[pos].l == t[pos].r) { t[pos].dat = v; return;} // 找到要修改的点
    	int mid = t[pos].l+t[pos].r >> 1;
    	if(x <= mid) change(x, v, pos << 1); // 要修改的点在当前点的左区间 =号和我建树有关
    	else change(x, v, pos<<1 | 1); // 要修改的点在当前点的右区间
    	t[pos].dat = max(t[pos << 1].dat, t[pos<<1 | 1].dat); // 找到叶结点后向上更新
    }
    inline int query(int l, int r, int pos) {
    	if(l <= t[pos].l && r >= t[pos].r) return t[pos].dat; // 当前点的区间完全在询问的区间中
    	int mid = t[pos].l+t[pos].r >> 1;
    	int val = -(1 << 30);
    	if(l <= mid) val = max(val, query(l, r, pos << 1) ); // 当前点的区间在询问点的左区间的部分的最大值 = 上下的有无是与建树方式有关
    	if(r > mid) val = max(val, query(l, r, pos<<1 | 1) ); // 当前点的区间在询问点的右区间的部分的最大值
    	return val;
    }
    //
    int main() {
    	//freopen("data1.in","r",stdin);
    	//freopen("data1.out","w",stdout);
    	//ios::sync_with_stdio(false);
    	scanf("%d%d", &n, &m);
    	for(int i = 1; i <= n; i ++) scanf("%d", &a[i]);
    	build(1, n, 1); //建树
    	for(int i = 0; i < m; i ++) {
    		scanf("%d%d", &x, &y);
    		if(x > y) swap(x, y); // 确保 x <= y
    		printf("%d
    ", query(x, y, 1));
    	}
    	return 0;
    }
    
  • 相关阅读:
    ActiveX Demo
    VC6 DLL exports
    进程间通信:剪切板
    Hook编程2:全局钩子
    Cookieless Session In WebService
    Report predicts possible PS3 launch delay
    原来是PS过的
    Xbox360日本卖不动.历代主机首周销量对比
    DirectX SDK (February 2006)
    vbo的速度问题,没有想象中快
  • 原文地址:https://www.cnblogs.com/RemnantDreammm/p/14127855.html
Copyright © 2020-2023  润新知