1 条题解

  • 0
    @ 2023-1-14 9:58:59

    单点修改,区间维护最小值的线段树。

    #include <cstdio>
    #include <algorithm>
    using namespace std;
    struct node {
    	int l, r, lc, rc, minn;
    }tr[400005];
    int a[200005];
    int build(int l, int r) {
    	static int cnt = 0;
    	int pos = ++cnt;
    	tr[pos].l = l;
    	tr[pos].r = r;
    	if (l == r) {
    		tr[pos].lc = tr[pos].rc = -1;
    		tr[pos].minn = a[l];
    	} else {
    		tr[pos].lc = build(l, l + r >> 1);
    		tr[pos].rc = build((l + r >> 1) + 1, r);
    		tr[pos].minn = min(tr[tr[pos].lc].minn, tr[tr[pos].rc].minn);
    	}
    	return pos;
    }
    void change(int pos, int x, int y) {
    	if (tr[pos].l == tr[pos].r) {
    		tr[pos].minn = y;
    		return;
    	}
    	if (x <= tr[tr[pos].lc].r)
    		change(tr[pos].lc, x, y);
    	else
    		change(tr[pos].rc, x, y);
    	tr[pos].minn = min(tr[tr[pos].lc].minn, tr[tr[pos].rc].minn);
    }
    int query(int pos, int l, int r) {
    	if (tr[pos].l == l && tr[pos].r == r)
    		return tr[pos].minn;
    	if (r <= tr[tr[pos].lc].r)
    		return query(tr[pos].lc, l, r);
    	if (l >= tr[tr[pos].rc].l)
    		return query(tr[pos].rc, l, r);
    	return min(query(tr[pos].lc, l, tr[tr[pos].lc].r), query(tr[pos].rc, tr[tr[pos].rc].l, r));
    }
    int main() {
    	int n, m;
    	scanf("%d%d", &n, &m);
    	for (int i = 1; i <= n; i++)
    		scanf("%d", &a[i]);
    	build(1, n);
    	while (m--) {
    		char c[2];
    		int a, b;
    		scanf("%s%d%d", c, &a, &b);
    		if (c[0] == 'Q') {
    			if (a > b)
    				swap(a, b);
    			printf("%d\n", query(1, a, b));
    		}
    		else
    			change(1, a, b);
    	}
    	return 0;
    }
    
    • 1

    信息

    ID
    19
    时间
    1000ms
    内存
    256MiB
    难度
    10
    标签
    递交数
    5
    已通过
    1
    上传者