美文网首页
线段树模板区间最大最小

线段树模板区间最大最小

作者: _弓长_大人 | 来源:发表于2018-09-25 12:44 被阅读8次
    // Asimple
    #include <iostream>
    #include <algorithm>
    #include <cstdio>
    #include <cstdlib>
    #include <queue>
    #include <vector>
    #include <string>
    #include <cstring>
    #include <stack>
    #include <set>
    #include <map>
    #include <cmath>
    #define INF 0x3f3f3f3f
    #define debug(a) cout<<#a<<" = "<<a<<endl
    #define test() cout<<"============"<<endl
    #define CLS(a,v) memset(a, v, sizeof(a))
    using namespace std;
    typedef long long ll;
    typedef unsigned long long ull;
    int dx[] = {-1,1,0,0,-1,-1,1,1}, dy[]={0,0,-1,1,-1,1,1,-1};
    const int maxn = 140000;
    const ll mod = 233;
    int n, m, T, len, cnt, num, ans, Max, k;
    int x, y;
    pair<int, int> dat[4*maxn];
    
    void init() {
        for (int i = 0; i < 2 * n - 1; ++i) {
            dat[i].first = INF;
            dat[i].second = -INF;
        }
    }
    void update(int k, int x) {
        k += n - 1;
        dat[k] = pair<int, int>(x, x);
        while (k > 0) {
            k = (k - 1) / 2;
            dat[k].first = min(dat[2 * k + 1].first, dat[2 * k + 2].first);
            dat[k].second = max(dat[2 * k + 1].second, dat[2 * k + 2].second);
        }
    }
    
    pair<int, int> query(int a, int b, int k, int l, int r) {
        if (a <= l && r <= b) return dat[k];
        if (a > r || b < l) return pair<int, int>(INF, -INF);
        pair<int, int> vl = query(a, b, 2 * k + 1, l, (l + r) / 2);
        pair<int, int> vr = query(a, b, 2 * k + 2, (l + r) / 2 + 1, r);
        return pair<int, int>(min(vl.first, vr.first), max(vl.second, vr.second));
    }
    
    void input(){
        for(scanf("%d", &T); T--; ) {
            scanf("%d", &k);
            n = (int)pow(2, k);
            init();
            for(int i=0; i<n; i++) {
                scanf("%d", &num);
                update(i, num);
            }
            for(scanf("%d", &m); m--; ) {
                scanf("%d%d%d",&k, &x, &y);
                if( k == 2 ) update(x, y);
                else {
                    pair<int, int> p = query(x, y, 0, 0, n-1);
                    ll ans = min((ll)p.first*p.first, min((ll)p.second*p.second, (ll)p.first*p.second));
                    printf("%lld\n", ans);
                }
            }
        }
    }
    
    int main() {
        input();
        return 0;
    }
    

    相关文章

      网友评论

          本文标题:线段树模板区间最大最小

          本文链接:https://www.haomeiwen.com/subject/xhxhextx.html