zoukankan      html  css  js  c++  java
  • hdu 4819 二维线段树模板

    /*
    HDU 4819 Mosaic
    题意:查询某个矩形内的最大最小值,
          修改矩形内某点的值为该矩形(Mi+MA)/2;
    二维线段树模板:
        区间最值,单点更新。
    */
    #include<bits/stdc++.h>
    using namespace std;
    const int INF = 0x3f3f3f3f;
    const int MAXN = 1010;
    int N, Q;
    struct Nodey
    {
        int l, r;
        int Max, Min;
    };
    int locx[MAXN], locy[MAXN];
    struct Nodex
    {
        int l, r;
        Nodey sty[MAXN * 4];
        void build(int i, int _l, int _r)
        {
            sty[i].l = _l;
            sty[i].r = _r;
            sty[i].Max = -INF;
            sty[i].Min = INF;
            if(_l == _r)
            {
                locy[_l] = i;
                return;
            }
            int mid = (_l + _r) / 2;
            build(i << 1, _l, mid);
            build((i << 1) | 1, mid + 1, _r);
        }
        int queryMin(int i, int _l, int _r)
        {
            if(sty[i].l == _l && sty[i].r == _r)
                return sty[i].Min;
            int mid = (sty[i].l + sty[i].r) / 2;
            if(_r <= mid)
                return queryMin(i << 1, _l, _r);
            else if(_l > mid)
                return queryMin((i << 1) | 1, _l, _r);
            else
                return min(queryMin(i << 1, _l, mid), queryMin((i << 1) | 1, mid + 1, _r));
        }
        int queryMax(int i, int _l, int _r)
        {
            if(sty[i].l == _l && sty[i].r == _r)
                return sty[i].Max;
            int mid = (sty[i].l + sty[i].r) / 2;
            if(_r <= mid)
                return queryMax(i << 1, _l, _r);
            else if(_l > mid)
                return queryMax((i << 1) | 1, _l, _r);
            else
                return max(queryMax(i << 1, _l, mid), queryMax((i << 1) | 1, mid + 1, _r));
        }
    } stx[MAXN * 4];
    void build(int i, int l, int r)
    {
        stx[i].l = l;
        stx[i].r = r;
        stx[i].build(1, 1, N);
        if(l == r)
        {
            locx[l] = i;
            return;
        }
        int mid = (l + r) / 2;
        build(i << 1, l, mid);
        build((i << 1) | 1, mid + 1, r);
    }
    //单点修改值
    void Modify(int x, int y, int val)
    {
        int tx = locx[x];
        int ty = locy[y];
        stx[tx].sty[ty].Min = stx[tx].sty[ty].Max = val;
        for(int i = tx; i; i >>= 1)
            for(int j = ty; j; j >>= 1)
            {
                if(i == tx && j == ty)continue;
                if(j == ty)
                {
                    stx[i].sty[j].Min = min(stx[i << 1].sty[j].Min, stx[(i << 1) | 1].sty[j].Min);
                    stx[i].sty[j].Max = max(stx[i << 1].sty[j].Max, stx[(i << 1) | 1].sty[j].Max);
                }
                else
                {
                    stx[i].sty[j].Min = min(stx[i].sty[j << 1].Min, stx[i].sty[(j << 1) | 1].Min);
                    stx[i].sty[j].Max = max(stx[i].sty[j << 1].Max, stx[i].sty[(j << 1) | 1].Max);
                }
            }
    }
    
    int queryMin(int i, int x1, int x2, int y1, int y2)
    {
        if(stx[i].l == x1 && stx[i].r == x2)
            return stx[i].queryMin(1, y1, y2);
        int mid = (stx[i].l + stx[i].r) / 2;
        if(x2 <= mid)
            return queryMin(i << 1, x1, x2, y1, y2);
        else if(x1 > mid)
            return queryMin((i << 1) | 1, x1, x2, y1, y2);
        else
            return min(queryMin(i << 1, x1, mid, y1, y2), queryMin((i << 1) | 1, mid + 1, x2, y1, y2));
    }
    int queryMax(int i, int x1, int x2, int y1, int y2)
    {
        if(stx[i].l == x1 && stx[i].r == x2)
            return stx[i].queryMax(1, y1, y2);
        int mid = (stx[i].l + stx[i].r) / 2;
        if(x2 <= mid)
            return queryMax(i << 1, x1, x2, y1, y2);
        else if(x1 > mid)
            return queryMax((i << 1) | 1, x1, x2, y1, y2);
        else
            return max(queryMax(i << 1, x1, mid, y1, y2), queryMax((i << 1) | 1, mid + 1, x2, y1, y2));
    }
    
    
    int main()
    {
        //freopen("in.txt","r",stdin);
        //freopen("out.txt","w",stdout);
        int T, ic = 0;
        scanf("%d", &T);
        while(T--)
        {
            printf("Case #%d:
    ", ++ic);
            scanf("%d", &N);
            build(1, 1, N);
            for(int i = 1; i <= N; i++)
                for(int j = 1; j <= N; j++)
                {
                    int a;
                    scanf("%d", &a);
                    Modify(i, j, a);
                }
            scanf("%d", &Q);
            while(Q--)
            {
                int x, y, L;
                scanf("%d%d%d", &x, &y, &L);
                int x1 = max(x - L / 2, 1);
                int x2 = min(x + L / 2, N);
                int y1 = max(y - L / 2, 1);
                int y2 = min(y + L / 2, N);
                //(x1,y1)左上角,(x2,y2)右下角
                int Max = queryMax(1, x1, x2, y1, y2);
                int Min = queryMin(1, x1, x2, y1, y2);
                int t = (Max + Min) / 2;
                printf("%d
    ", t);
                Modify(x, y, t);//单点修改
            }
        }
        return 0;
    }
  • 相关阅读:
    How To Compile Qt with Visual Studio 2010
    VCL线程的同步方法 Synchronize(用消息来同步)
    Delphi中怎么结束线程(这个线程是定时执行的)(方案二)
    编程之美 寻找数组中的最大值和最小值
    Delphi中怎么结束线程(这个线程是定时执行的)(方案一)
    Delphi线程同步(临界区、互斥、信号量,包括详细代码)
    Delphi管理多线程之线程局部存储:threadvar
    Delphi之通过代码示例学习XML解析、StringReplace的用法(异常控制 good)
    Delphi的文件操作(定义,关联,打开,读写,关闭)
    Android 中单位讲解
  • 原文地址:https://www.cnblogs.com/pealicx/p/7327224.html
Copyright © 2011-2022 走看看