3 条题解

  • 0
    @ 2025-9-12 10:51:13
    • 树状数组实现
    • 单点更新复杂度:O(log(n)×log(n))O(log(n) \times log(n)),不算优秀
    • 区间最值复杂度:O(log(n))O(log(n))
    • 这个写法虽然写起来简单,但时间复杂度不如线段树优秀,大家了解就好
    // 参考资料
    // https://oi-wiki.org/ds/fenwick/
    // https://www.cnblogs.com/ambition/archive/2011/04/06/bit_rmq.html
    
    // hdu 1754
    // https://acm.hdu.edu.cn/viewcode.php?rid=40390236
    // 873ms
    
    // LS1227
    // https://www.gzlzoi.cn/d/lzoi2025/record/68c37804e1b585b55d44fcf6
    // 67ms
    
    #include <bits/stdc++.h>
    using namespace std;
    
    const int inf = numeric_limits<int>::max() / 2;
    
    template <typename T>  // 使用 template 模板, 用法见定义
    struct Fenwick {
    	int n;
    	vector<T> a, o;  // a: 树状数组, o: 原数组
    	
    	Fenwick(int n_) : n(n_) {
    		// 注意: 树状数组都是从 1 开始编号 a[1..n], 不要从 0 开始
    		// 相当于 a = vector<int>(n + 1, 0)
    		a.assign(n + 1, 0);  // 树状数组
    		
    		o.assign(n + 1, 0);  // 原数组
    	}
    	
    	// 将原数组的第 p 个数修改为 v, o[p] = v
    	// O(log(n) ^2)
    	void update(int p, T v) {
    		
    		o[p] = v;  // 先修改原数组
    		
    		// 所有包含 o[p] 的都要更新
    		for (; p <= n; p += p & -p) {
    			a[p] = o[p];  
    			int l = p - (p & -p) + 1, r = p - 1;
    			while (l <= r) {
    				int d = r & -r;
    				if (r - d + 1 >= l) a[p] = max(a[p], a[r]), r -= d;
    				else a[p] = max(a[p], o[r]), r--;
    			}
    		}
    	}
    	
    	// 求 [l, r] 区间最值
    	// O(log(n))
    	T query(int l, int r) {
    		T ans = 0;
    		while (l <= r) {
    			int d = r & -r;
    			if (r - d + 1 >= l) ans = max(ans, a[r]), r -= d;
    			else ans = max(ans, o[r]), r--;
    		}
    		return ans;
    	}
    
    };
    
    int main() {
    	ios::sync_with_stdio(false);
    	cin.tie(0); cout.tie(0);
    	
    	int n, q, x, p, l, r, cmd;
    	cin >> n >> q;
    	
    	Fenwick<int> f(n);
    	for (int i = 1; i <= n; i++) {
    		cin >> x;
    		f.update(i, x);
    	}
    	
    	while (q--) {
    		cin >> cmd;
    		if (cmd == 1) {
    			cin >> p >> x;
    			f.update(p, x);
    		} else {
    			cin >> l >> r;
    			cout << f.query(l, r) << '\n';
    		}
    	}
    	return 0;
    }
    

    信息

    ID
    124
    时间
    200ms
    内存
    64MiB
    难度
    7
    标签
    递交数
    84
    已通过
    19
    上传者