题目

多组数据,给定一个\(n*n\)的矩阵(\(n\leq 80,a_{i,j}\leq 10^9\))

多组询问一个以\((x,y)\)为中心,边长为\(L\)的子矩阵最大值\(mx\)和最小值\(mn\),

并将\((x,y)\)这一个位置修改为\(\lfloor\frac{mn+mx}{2}\rfloor\),每次询问输出修改后的\((x,y)\)


分析

二维线段树裸题,反正之前也没敲过,

其实和一维线段树相近,找到\(lx\sim rx\)的下标

再按照一维线段树的方式修改最大最小值就可以了


代码

#include <cstdio>
#include <cctype>
#define rr register
using namespace std;
const int N=801,M=3201; struct rec{int x,y;};
int wmn[M][M],wmx[M][M],ans,n,a[N][N];
inline signed iut(){
rr int ans=0; rr char c=getchar();
while (!isdigit(c)) c=getchar();
while (isdigit(c)) ans=(ans<<3)+(ans<<1)+(c^48),c=getchar();
return ans;
}
inline void print(int ans){
if (ans>9) print(ans/10);
putchar(ans%10+48);
}
inline signed min(int a,int b){return a<b?a:b;}
inline signed max(int a,int b){return a>b?a:b;}
inline void pupx(int kx,int ky){
wmn[kx][ky]=min(wmn[kx<<1][ky],wmn[kx<<1|1][ky]);
wmx[kx][ky]=max(wmx[kx<<1][ky],wmx[kx<<1|1][ky]);
}
inline void pupy(int kx,int ky){
wmn[kx][ky]=min(wmn[kx][ky<<1],wmn[kx][ky<<1|1]);
wmx[kx][ky]=max(wmx[kx][ky<<1],wmx[kx][ky<<1|1]);
}
inline void buildy(int ky,int kx,int l,int r,int z){
if (l==r){
if (z) wmn[kx][ky]=wmx[kx][ky]=a[z][l];
else pupx(kx,ky);
return;
}
rr int mid=(l+r)>>1;
buildy(ky<<1,kx,l,mid,z);
buildy(ky<<1|1,kx,mid+1,r,z);
pupy(kx,ky);
}
inline void buildx(int k,int l,int r){
if (l==r){
buildy(1,k,1,n,l);
return;
}
rr int mid=(l+r)>>1;
buildx(k<<1,l,mid);
buildx(k<<1|1,mid+1,r);
buildy(1,k,1,n,0);
}
inline void updatey(rec K,int l,int r,rec t,int z){
if (l==t.x&&r==t.y){
if (z) wmn[K.x][K.y]=wmx[K.x][K.y]=ans;
else pupx(K.x,K.y);
return;
}
rr int mid=(l+r)>>1;
if (t.y<=mid) updatey((rec){K.x,K.y<<1},l,mid,t,z);
else if (t.x>mid) updatey((rec){K.x,K.y<<1|1},mid+1,r,t,z);
else {
updatey((rec){K.x,K.y<<1},l,mid,(rec){t.x,mid},z);
updatey((rec){K.x,K.y<<1|1},mid+1,r,(rec){mid+1,t.y},z);
}
pupy(K.x,K.y);
}
inline void updatex(int k,int l,int r,rec L,rec R){
if (l==L.x&&r==L.y){
updatey((rec){k,1},1,n,R,1);
return;
}
rr int mid=(l+r)>>1;
if (L.y<=mid) updatex(k<<1,l,mid,L,R);
else if (L.x>mid) updatex(k<<1|1,mid+1,r,L,R);
else {
updatex(k<<1,l,mid,(rec){L.x,mid},R);
updatex(k<<1|1,mid+1,r,(rec){mid+1,L.y},R);
}
updatey((rec){k,1},1,n,R,0);
}
inline void queryy(rec K,int l,int r,rec t,int &mn,int &mx){
if (l==t.x&&r==t.y){
mn=min(mn,wmn[K.x][K.y]),
mx=max(mx,wmx[K.x][K.y]);
return;
}
rr int mid=(l+r)>>1;
if (t.y<=mid) queryy((rec){K.x,K.y<<1},l,mid,t,mn,mx);
else if (t.x>mid) queryy((rec){K.x,K.y<<1|1},mid+1,r,t,mn,mx);
else {
queryy((rec){K.x,K.y<<1},l,mid,(rec){t.x,mid},mn,mx);
queryy((rec){K.x,K.y<<1|1},mid+1,r,(rec){mid+1,t.y},mn,mx);
}
}
inline void queryx(int k,int l,int r,rec L,rec R,int &mn,int &mx){
if (l==L.x&&r==L.y){
queryy((rec){k,1},1,n,R,mn,mx);
return;
}
rr int mid=(l+r)>>1;
if (L.y<=mid) queryx(k<<1,l,mid,L,R,mn,mx);
else if (L.x>mid) queryx(k<<1|1,mid+1,r,L,R,mn,mx);
else {
queryx(k<<1,l,mid,(rec){L.x,mid},R,mn,mx);
queryx(k<<1|1,mid+1,r,(rec){mid+1,L.y},R,mn,mx);
}
}
signed main(){
for (rr int Test=iut(),T=1;T<=Test;++T){
printf("Case #%d:\n",T),n=iut();
for (rr int i=1;i<=n;++i)
for (rr int j=1;j<=n;++j) a[i][j]=iut();
buildx(1,1,n);
for (rr int Q=iut();Q;--Q){
rr int x=iut(),y=iut(),L=(iut()-1)>>1;
rr int lx=max(x-L,1),ly=max(y-L,1),mx=0;
rr int rx=min(x+L,n),ry=min(y+L,n),mn=1e9;
queryx(1,1,n,(rec){lx,rx},(rec){ly,ry},mn,mx),
ans=(mx+mn)>>1,lx=rx=x,ly=ry=y;
print(ans),putchar(10),
updatex(1,1,n,(rec){lx,rx},(rec){ly,ry});
}
}
return 0;
}

#树套树,二维线段树#HDU 4819 Mosaic的更多相关文章

  1. bzoj4785:[ZJOI2017]树状数组:二维线段树

    分析: "如果你对树状数组比较熟悉,不难发现可怜求的是后缀和" 设数列为\(A\),那么可怜求的就是\(A_{l-1}\)到\(A_{r-1}\)的和(即\(l-1\)的后缀减\( ...

  2. BZOJ 4785 [Zjoi2017]树状数组 | 二维线段树

    题目链接 BZOJ 4785 题解 这道题真是令人头秃 = = 可以看出题面中的九条可怜把求前缀和写成了求后缀和,然后他求的区间和却仍然是sum[r] ^ sum[l - 1],实际上求的是闭区间[l ...

  3. 算法模板——线段树6(二维线段树:区域加法+区域求和)(求助phile)

    实现功能——对于一个N×M的方格,1:输入一个区域,将此区域全部值作加法:2:输入一个区域,求此区域全部值的和 其实和一维线段树同理,只是不知道为什么速度比想象的慢那么多,求解释...@acphile ...

  4. HDU 4819 Mosaic --二维线段树(树套树)

    题意: 给一个矩阵,每次查询一个子矩阵内的最大最小值,然后更新子矩阵中心点为(Max+Min)/2. 解法: 由于是矩阵,且要求区间最大最小和更新单点,很容易想到二维的线段树,可是因为之前没写过二维的 ...

  5. HDU 1823 Luck and Love 二维线段树(树套树)

    点击打开链接 Luck and Love Time Limit: 10000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Ot ...

  6. HDU 4819 Mosaic(13年长春现场 二维线段树)

    HDU 4819 Mosaic 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4819 题意:给定一个n*n的矩阵,每次给定一个子矩阵区域(x,y,l) ...

  7. poj 2155 matrix 二维线段树 线段树套线段树

    题意 一个$n*n$矩阵,初始全为0,每次翻转一个子矩阵,然后单点查找 题解 任意一种能维护二维平面的数据结构都可以 我这里写的是二维线段树,因为四分树的写法复杂度可能会退化,因此考虑用树套树实现二维 ...

  8. BZOJ.4553.[HEOI2016&TJOI2016]序列(DP 树状数组套线段树/二维线段树(MLE) 动态开点)

    题目链接:BZOJ 洛谷 \(O(n^2)\)DP很好写,对于当前的i从之前满足条件的j中选一个最大值,\(dp[i]=d[j]+1\) for(int j=1; j<i; ++j) if(a[ ...

  9. hdu 4819 二维线段树模板

    /* HDU 4819 Mosaic 题意:查询某个矩形内的最大最小值, 修改矩形内某点的值为该矩形(Mi+MA)/2; 二维线段树模板: 区间最值,单点更新. */ #include<bits ...

  10. UVA 11297 线段树套线段树(二维线段树)

    题目大意: 就是在二维的空间内进行单个的修改,或者进行整块矩形区域的最大最小值查询 二维线段树树,要注意的是第一维上不是叶子形成的第二维线段树和叶子形成的第二维线段树要  不同的处理方式,非叶子形成的 ...

随机推荐

  1. OpenCV计数应用 c++(QT)

    一.前言 为了挑战一下OpenCV的学习成果,最经一直在找各类项目进行实践.机缘巧合之下,得到了以下的需求: 要求从以下图片中找出所有的近似矩形的点并计数,重叠点需要拆分单独计数. 二.解题思路 1. ...

  2. 【Azure 微服务】记一次错误的更新Service Fabric 证书而引发的集群崩溃而只能重建

    问题描述 错误的操作步骤: 1)更新Service Fabric 的证书,制定了次要证书(Secondary),但是只修改了Service Fabric Cluster证书,而没有指定VMSS(虚拟机 ...

  3. 【Azure Developer】使用Azure Resource Graph的查询语法的示例

    文章"[Azure Developer]在Azure Resource Graph Explorer中查看当前订阅下的所有资源信息列表并导出(如VM的名称,IP地址内网/公网,OS,区域等) ...

  4. 使用 Java 在Excel中创建下拉列表

    下拉列表(下拉框)可以确保用户仅从预先给定的选项中进行选择,这样不仅能减少数据输入错误,还能节省时间提高效率.在MS Excel中,我们可以通过 "数据验证" 提供的选项来创建下拉 ...

  5. 将windows上socket的client程序修改到linux上运行

    将windows上客户端程序修改到linux上运行 记录一下修改哪些地方 编译命令 文件夹的内容:包含了client.cpp mySocket.cpp mySocket.h until.h 链接在一起 ...

  6. jenkins 钉钉机器人插件

    官方文档: https://jenkinsci.github.io/dingtalk-plugin/guide/getting-started.html#%E6%B3%A8%E6%84%8F 注意:系 ...

  7. 计算机网络-IP地址

    目录 子网划分 定长子网划分 子网划分的方法 子网掩码 可变长子网划分 无类别编址 网络前缀 路由聚合 特殊用途的IP地址 专用网络地址 链路本地地址 运营商级NAT共享地址 用于文档的测试网络地址 ...

  8. 并行化优化KD树算法:使用C#实现高效的最近邻搜索

    本文信息 中文名:<并行化优化KD树算法:使用C#实现高效的最近邻搜索> 英文名:"Parallelized Optimization of KD-Tree Algorithm: ...

  9. windows10 使用gcc编译生成可执行文件exe实例解析

    一 操作步骤 1.生成可执行程序 cd xxx # 先进入源程序所在的目录 gcc hello.cpp # 一次性编译,windows系统生成a.exe文件,Linux系统生成a.out文件 gcc ...

  10. Docker部署nginx配置SSL多目录

    对自己第一次搭建nginx做个简要的笔记 第一步:创建宿主机挂载点目录 mkdir -p /home/nginx/{conf,conf.d,html,log,ssl} 第二步:安装简易版nginx,复 ...