1 条题解

  • 0
    @ 2024-1-30 17:24:55

    区间最值问题。

    问区间最值,但不存在修改的操作。

    STST 表(倍增):支持查询任意区间 [l,r][l, r],但是不支持修改。

    查询复杂度 O(1)O(1)

    建表复杂度 O(nlogn)O(nlogn)

    STST 表的本质是动态对话求区间最值。

    1. 状态:dp[i][j]dp[i][j]ii 为起点长度为 2j2^j 的区间最值 min[i,i+2j1]min[i, i + 2 ^ j -1]

    2. 状态转移方程:$dp[i][j] = min(dp[i][j - 1], dp[i + 2 ^ {j - 1}][j - 1])$。

    3. 初始化:dp[i][0]=a[i]dp[i][0] = a[i]

    4. 对于任意区间如何查询。

    [l,r][l, r] 长度为 len=rl+1len = r - l + 1

    先求出最大的 2ilen2^i \le len

    min(dp[l][i],dp[r2i+1][i])min(dp[l][i], dp[r - 2^i + 1][i])

    
    void init() {
    	for (int j = 1; (1 << j) <= n; j++) {
    		for (int i = 1; i + (1 << j) - 1 <= n; i++) {
    			dp[i][j] = min(dp[i][j - 1], dp[i + (1 << (j - 1))][j - 1]);
    		}
    	}
    }
    
    int query(int l, int r) {
    	int i = (int)(log2(r - l + 1));
    	return max(dp[l][i], dp[r - (1 << i) + 1][i]);
    }
    	
    int main() {
        cin >> n >> m;
        for (int i = 1; i <= n; i++) {
    	    cin >> a[i];
    	    dp[i][0] = a[i];
        }
        init();
        while (m--) {
    	    int l, r;
    	    cin >> l >> r;
    	    cout << query(l, r) << "\n";
        }
        return 0;
    }
    
    #include <bits/stdc++.h>
    using namespace std;
    
    typedef long long ll;
    const int N = 1e5 + 10;
    int a[N], dp[N][21];
    int n, m;
    
    inline int read()
    {
        char c=getchar();int x=0,f=1;
        while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
        while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
        return x*f;
    }
    
    int query(int l, int r) {
        int i = log2(r - l + 1);
        return max(dp[l][i],  dp[r - (1 << i) + 1][i]);
    }
    
    int main() {
    	n = read(), m = read();
        for (int i = 1; i <= n; i++) {
            a[i] = read();
            dp[i][0] = a[i];
        }
        for (int j = 1; j <= 21; j++) {
            for (int i = 1; i + (1 << j) - 1 <= n; i++) {
                dp[i][j] = max(dp[i][j - 1], dp[i + (1 << (j - 1))][j - 1]);
            }
        }
        while (m--) {
            int l, r;
            l = read(), r = read();
            cout << query(l, r) << "\n";
        }
        return 0;
    }
    
    • 1

    信息

    ID
    503
    时间
    1000ms
    内存
    256MiB
    难度
    8
    标签
    (无)
    递交数
    47
    已通过
    9
    上传者