• HDU 4819 Mosaic(二维线段树)


    给定一个矩阵,查询一块子矩阵的最大值和最小值,然后他们和的一半替换(x, y)这个位置,裸的二维线段树。

    和一维差不多,只不过是一维当中保存的是最值,而这个保存的是个数组而已,而这个数组也是个一维的线段树,所以就是二维线段树。具体见代码注释。

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    const int maxn = 1000;
    //每个x节点上有个纵向的y数组,就是一列
    struct Nodey {
        int l, r;
        int Max, Min;
    };
    int locx[maxn], locy[maxn];//对于给定的矩阵当中的位置(x, y)在线段树中对应的x和y的位置为locx[x], locy[y];
    const int inf = 0x3f3f3f3f;
    int T, n;//n矩阵的大小
    struct Nodex {//x节点,就是普通的一维的线段树
        int l, r;
        Nodey sty[maxn<<2];//它的节点不是一个普通的值,而是一维的数组,其实就是一列
        void build(int rt, int ll, int rr)//对于一列建树,和一维一样,注意区分ll和l,ll是列当中的区间左值,而l是行当中的区间左值
        {
            sty[rt].l = ll;
            sty[rt].r = rr;
            sty[rt].Min = inf;
            sty[rt].Max = -inf;
            if (ll == rr)
            {
                locy[ll] = rt;//位置
                return;
            }
            int mid = (ll + rr) / 2;
            build(rt << 1, ll, mid);
            build(rt << 1 | 1, mid + 1, rr);
        }
        int queryMin(int rt, int ll, int rr)//查询列当中ll-rr区间当中的最值
        {
            if (sty[rt].l == ll && sty[rt].r == rr)
                return sty[rt].Min;
            int mid = (sty[rt].l + sty[rt].r) / 2;
            if (rr <= mid) return queryMin(rt << 1, ll, rr);
            else if (ll > mid) return queryMin(rt << 1 | 1, ll, rr);
            return min(queryMin(rt << 1, ll, mid), queryMin(rt << 1 | 1, mid + 1, rr));
        }
        int queryMax(int rt, int ll, int rr)
        {
            if (sty[rt].l == ll && sty[rt].r == rr)
                return sty[rt].Max;
            int mid = (sty[rt].l + sty[rt].r) / 2;
            if (rr <= mid) return queryMax(rt << 1, ll, rr);
            else if (ll > mid) return queryMax(rt << 1 | 1, ll, rr);
            return max(queryMax(rt << 1, ll, mid), queryMax(rt << 1 | 1, mid + 1, rr));
        }
    }stx[maxn<<2];
    void build(int rt, int l, int r)//建树
    {
        stx[rt].l = l;
        stx[rt].r = r;
        stx[rt].build(1, 1, n);
        if (l == r)
        {
            locx[l] = rt;
            return;
        }
        int mid = (l + r) / 2;
        build(rt << 1, l, mid);
        build(rt << 1 | 1, mid + 1, r);
    }
    void modify(int x, int y, int val)//更改(x, y)这个点的值
    {
        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)//向上更新 PushUp
            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 rt, int x1, int x2, int y1, int y2)//查询在矩阵行为(x1 到 x2),列为(y1 到 y2)的最值
    {
        if (stx[rt].l == x1 && stx[rt].r == x2)
            return stx[rt].queryMin(1, y1, y2);
        int mid = (stx[rt].l + stx[rt].r) / 2;
        if (x2 <= mid) return queryMin(rt << 1, x1, x2, y1, y2);
        else if (x1 > mid) return queryMin(rt << 1 | 1, x1, x2, y1, y2);
        return min(queryMin(rt << 1, x1, mid, y1, y2), queryMin(rt << 1 | 1, mid + 1, x2, y1, y2));
    }
    int queryMax(int rt, int x1, int x2, int y1, int y2)
    {
        if (stx[rt].l == x1 && stx[rt].r == x2)
            return stx[rt].queryMax(1, y1, y2);
        int mid = (stx[rt].l + stx[rt].r) / 2;
        if (x2 <= mid) return queryMax(rt << 1, x1, x2, y1, y2);
        else if (x1 > mid) return queryMax(rt << 1 | 1, x1, x2, y1, y2);
        return max(queryMax(rt << 1, x1, mid, y1, y2), queryMax(rt << 1 | 1, mid + 1, x2, y1, y2));
    }
    int main()
    {
        scanf("%d", &T);
        int kase = 0;
        while (T--)
        {
            scanf("%d", &n);
            build(1, 1, n);//建树
            int mat;
            printf("Case #%d:
    ", ++kase);
            for (int i = 1; i <= n; i++)
                for (int j = 1; j <= n; j++)
                {
                    scanf("%d", &mat);
                    modify(i, j, mat);//更新
                }
            int q;
            scanf("%d", &q);
            while (q--)
            {
                int x, y, len;
                scanf("%d %d %d", &x, &y, &len);
                len /= 2;
                int x1 = max(x - len, 1);
                int x2 = min(x + len, n);
                int y1 = max(y - len, 1);
                int y2 = min(y + len, n);
                int Max = queryMax(1, x1, x2, y1, y2);
                int Min = queryMin(1, x1, x2, y1, y2);
                int ans = (Min + Max) / 2;
                printf("%d
    ", ans);
                modify(x, y, ans);
    
            }
        }
        return 0;
    }
  • 相关阅读:
    阿里PAI深度学习组件:Tensorflow实现图片智能分类实验
    IDEA with MaxCompute Stadio
    阿里云大数据产品解决方案ODPSADSSTERAMCOMPUTEPAI介绍
    Hive DDL ROW FORMAT
    Spark-Streaming和Kafka集成指南
    网站分析指标
    网站分析概要
    前端规范大总结
    不容错过的20段CSS代码
    利用CSS实现居中对齐
  • 原文地址:https://www.cnblogs.com/Howe-Young/p/4874176.html
Copyright © 2020-2023  润新知