HDU 4819 Mosaic(二维线段树+单点更新)

来源:互联网 发布:淘宝店铺装修素材包 编辑:程序博客网 时间:2024/05/20 06:37

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4819

题意:给出一个n*n的矩阵,q个查询,每次查询输入x,y,d(奇数)。
对于每次的x,y,d,对应一个矩阵区域为以(x,y)为中心,d为边长的子矩阵。
输出该子矩阵的(最大值+最小值) / 2 。并且更新点(x,y)的值为该值。

思路:以x建一棵线段树,对于x线段树中的每个节点,建一棵y的线段树。然后搞就可以了= =

代码:

#include <stdio.h>#include <iostream>#include <math.h>#include <algorithm>#include <string.h>#include <queue>#include <list>#include <stack>#include <vector>#include <set>using namespace std;#define LSON l, m, rt << 1#define RSON m + 1, r, rt << 1 | 1const int N = 8e2 + 10;const int M = 4e4 + 10;const int INF =  0x7fffffff;typedef pair<int, int> node;struct Ynode {    int minn;    int maxn;};struct Xnode {    int l, r;    Ynode yn[N << 2];}xn[N << 2];int a[N][N];int n;void buildY(int xi, int l, int r, int rt) {    Xnode &now = xn[xi];    if (l == r) {        now.yn[rt].minn = INF;        now.yn[rt].maxn = -INF;        for (int i = now.l; i <= now.r; i++) {            now.yn[rt].minn = min(now.yn[rt].minn, a[i][l]);            now.yn[rt].maxn = max(now.yn[rt].maxn, a[i][l]);        }        return ;    }    int m = (l + r) >> 1;    buildY(xi, LSON);    buildY(xi, RSON);    now.yn[rt].minn = min(now.yn[rt << 1].minn, now.yn[rt << 1 | 1].minn);    now.yn[rt].maxn = max(now.yn[rt << 1].maxn, now.yn[rt << 1 | 1].maxn);}void buildX(int l, int r, int rt) {    xn[rt].l = l;    xn[rt].r = r;    buildY(rt, 1, n, 1);    if (l == r)        return ;    int m = (l + r) >> 1;    buildX(LSON);    buildX(RSON);}void updateY(int val, int xi, int y, int l, int r, int rt) {    Xnode &now = xn[xi];    if (l == r) {        if (xn[xi].l == xn[xi].r) {//如果是更新单点值            xn[xi].yn[rt].minn = xn[xi].yn[rt].maxn = val;        }        else {//如果更新区间值            now.yn[rt].minn = INF;            now.yn[rt].maxn = -INF;            for (int i = xn[xi].l; i <= xn[xi].r; i++) {                now.yn[rt].minn = min(now.yn[rt].minn, a[i][l]);                now.yn[rt].maxn = max(now.yn[rt].maxn, a[i][l]);            }        }        return ;    }    int m = (l + r) >> 1;    if (y <= m)        updateY(val, xi, y, LSON);    else        updateY(val, xi, y, RSON);    now.yn[rt].minn = min(now.yn[rt << 1].minn, now.yn[rt << 1 | 1].minn);    now.yn[rt].maxn = max(now.yn[rt << 1].maxn, now.yn[rt << 1 | 1].maxn);}void updateX(int val, int x, int y, int l, int r, int rt) {    updateY(val, rt, y, 1, n, 1);//包含y的x线段树节点均需要更新    if (l == r) return ;    int m = (l + r) >> 1;    if (x <= m)        updateX(val, x, y, LSON);    else        updateX(val, x, y, RSON);}node queryY(int xi, int L, int R, int l, int r, int rt) {    Xnode &now = xn[xi];    if (L <= l && r <= R)        return node(now.yn[rt].minn, now.yn[rt].maxn);    int m = (l + r) >> 1;    node ql = node(INF, -INF), qr = node(INF, -INF);    if (L <= m)        ql = queryY(xi, L, R, LSON);    if (R > m)        qr = queryY(xi, L, R, RSON);    return node(min(ql.first, qr.first), max(ql.second, qr.second));}node queryX(int XL, int XR, int YL, int YR, int l, int r, int rt) {    if (XL <= l && r <= XR)        return queryY(rt, YL, YR, 1, n, 1);    int m = (l + r) >> 1;    node ql = node(INF, -INF), qr = node(INF, -INF);    if (XL <= m)        ql = queryX(XL, XR, YL, YR, LSON);    if (XR > m)        qr = queryX(XL, XR, YL, YR, RSON);    return node(min(ql.first, qr.first), max(ql.second, qr.second));}int main() {        int t_case;    scanf("%d", &t_case);    for (int i_case = 1; i_case <= t_case; i_case++) {        scanf("%d", &n);        for (int i = 1; i <= n; i++)            for (int j = 1; j <= n; j++)                scanf("%d", &a[i][j]);        buildX(1, n, 1);        int q;        scanf("%d", &q);        printf("Case #%d:\n", i_case);        for (int i_q = 1; i_q <= q; i_q++) {            int x, y, d;            scanf("%d%d%d", &x, &y, &d);            int xl = max(1, x - d / 2);            int xr = min(n, x + d / 2);            int yl = max(1, y - d / 2);            int yr = min(n, y + d / 2);            node res = queryX(xl, xr, yl, yr, 1, n, 1);            printf("%d\n", (res.first + res.second) / 2);            a[x][y] = (res.first + res.second) / 2;//修改矩阵值            updateX((res.first + res.second) / 2, x, y, 1, n, 1);        }    }    return 0;}
0 0