zoukankan      html  css  js  c++  java
  • HDU4819 Mosaic【树套树】

    LINK

    题目大意

    给你一个(n*n)矩阵,每个点有初始权值

    q次询问每次把一个矩形的中心节点变成这个矩形中最大值和最小值的平均数

    思路

    很显然的树套树啊

    就是一开始傻逼了没想到怎么去维护这个东西

    其实很简单

    对于每个内层树,如果属于外层树的叶子节点,那么可以直接暴力更新,复杂度(O(log(n)))

    void modify_y(int t, int l, int r, int pos, int vl, int id) {
      if (l == r) {
        minv[id][t] = vl;
        maxv[id][t] = vl;
        return;
      }
      int mid = (l + r) >> 1;
      if (pos <= mid) modify_y(LD(t), l, mid, pos, vl, id);
      else modify_y(RD(t), mid + 1, r, pos, vl, id);
      pushup(t, id);
    }
    

    然后如果要更新不是叶子节点外层树对应的内层树怎么办?

    考虑从外层树的儿子节点合并对应的信息,只需要修改有影响的一条链,复杂度(O(nlog(n)))

    void update_y(int t, int l, int r, int pos, int id) {
      if (l == r) {
        minv[id][t] = min(minv[LD(id)][t], minv[RD(id)][t]);
        maxv[id][t] = max(maxv[LD(id)][t], maxv[RD(id)][t]);
        return;
      }
      int mid = (l + r) >> 1;
      if (pos <= mid) update_y(LD(t), l, mid, pos, id);
      else update_y(RD(t), mid + 1, r, pos, id);
      pushup(t, id);
    }
    

    内层树的查询就简单而套路了

    pi query_y(int t, int l, int r,int ql, int qr, int id) {
      if (ql <= l && r <= qr) return pi(maxv[id][t], minv[id][t]);
      int mid = (l + r) >> 1;
      if (qr <= mid) return query_y(LD(t), l, mid, ql, qr, id);
      else if (ql > mid) return query_y(RD(t), mid + 1, r, ql, qr, id);
      else {
        pi ansl = query_y(LD(t), l, mid, ql, mid, id);
        pi ansr = query_y(RD(t), mid + 1, r, mid + 1, qr, id);
        return pi(max(ansl.first, ansr.first), min(ansl.second, ansr.second));
      }
    }
    

    外层树修改的时候需要判断一下当前节点是不是叶子,如果是叶子直接更新y

    否则先递归问题再调用(update_y)函数

    void modify_x(int t, int l, int r, int x, int y, int vl) {
      if (l == r) {
        modify_y(1, 1, n, y, vl, t);
        return;
      }
      int mid = (l + r) >> 1;
      if (x <= mid) modify_x(LD(t), l, mid, x, y, vl);
      else modify_x(RD(t), mid + 1, r, x, y, vl);
      update_y(1, 1, n, y, t);
    }
    

    外层树的查询就是如果被查询区间包含调用内层查询,否则递归问题

    pi query_x(int t, int l, int r, int xl, int xr, int yl, int yr) {
      if (xl <= l && r <= xr) return query_y(1, 1, n, yl, yr, t);
      int mid = (l + r) >> 1;
      if (xr <= mid) return query_x(LD(t), l, mid, xl, xr, yl, yr);
      else if (xl > mid) return query_x(RD(t), mid + 1, r, xl, xr, yl, yr);
      else {
        pi ansl = query_x(LD(t), l, mid, xl, mid, yl, yr);
        pi ansr = query_x(RD(t), mid + 1, r, mid + 1, xr, yl, yr);
        return pi(max(ansl.first, ansr.first), min(ansl.second, ansr.second));
      }
    }
    
  • 相关阅读:
    servlet-servletConfig
    servlet-servletContext网站计数器
    servlet-cookie
    Android 无cp命令 mv引起cross-device link
    android使用mount挂载/system/app为读写权限,删除或替换系统应用
    android使用百度地图、定位SDK实现地图和定位功能!(最新、可用+吐槽)
    解决android sdk manager无法下载SDK 的问题
    Android APK反编译详解(附图)
    Android如何防止apk程序被反编译
    不用外部JAR包,自己实现JSP文件上传!
  • 原文地址:https://www.cnblogs.com/dream-maker-yk/p/9867915.html
Copyright © 2011-2022 走看看