#树套树,二维线段树#HDU 4819 Mosaic
题目
多组数据,给定一个\(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的更多相关文章
- bzoj4785:[ZJOI2017]树状数组:二维线段树
分析: "如果你对树状数组比较熟悉,不难发现可怜求的是后缀和" 设数列为\(A\),那么可怜求的就是\(A_{l-1}\)到\(A_{r-1}\)的和(即\(l-1\)的后缀减\( ...
- BZOJ 4785 [Zjoi2017]树状数组 | 二维线段树
题目链接 BZOJ 4785 题解 这道题真是令人头秃 = = 可以看出题面中的九条可怜把求前缀和写成了求后缀和,然后他求的区间和却仍然是sum[r] ^ sum[l - 1],实际上求的是闭区间[l ...
- 算法模板——线段树6(二维线段树:区域加法+区域求和)(求助phile)
实现功能——对于一个N×M的方格,1:输入一个区域,将此区域全部值作加法:2:输入一个区域,求此区域全部值的和 其实和一维线段树同理,只是不知道为什么速度比想象的慢那么多,求解释...@acphile ...
- HDU 4819 Mosaic --二维线段树(树套树)
题意: 给一个矩阵,每次查询一个子矩阵内的最大最小值,然后更新子矩阵中心点为(Max+Min)/2. 解法: 由于是矩阵,且要求区间最大最小和更新单点,很容易想到二维的线段树,可是因为之前没写过二维的 ...
- HDU 1823 Luck and Love 二维线段树(树套树)
点击打开链接 Luck and Love Time Limit: 10000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Ot ...
- HDU 4819 Mosaic(13年长春现场 二维线段树)
HDU 4819 Mosaic 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4819 题意:给定一个n*n的矩阵,每次给定一个子矩阵区域(x,y,l) ...
- poj 2155 matrix 二维线段树 线段树套线段树
题意 一个$n*n$矩阵,初始全为0,每次翻转一个子矩阵,然后单点查找 题解 任意一种能维护二维平面的数据结构都可以 我这里写的是二维线段树,因为四分树的写法复杂度可能会退化,因此考虑用树套树实现二维 ...
- 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[ ...
- hdu 4819 二维线段树模板
/* HDU 4819 Mosaic 题意:查询某个矩形内的最大最小值, 修改矩形内某点的值为该矩形(Mi+MA)/2; 二维线段树模板: 区间最值,单点更新. */ #include<bits ...
- UVA 11297 线段树套线段树(二维线段树)
题目大意: 就是在二维的空间内进行单个的修改,或者进行整块矩形区域的最大最小值查询 二维线段树树,要注意的是第一维上不是叶子形成的第二维线段树和叶子形成的第二维线段树要 不同的处理方式,非叶子形成的 ...
随机推荐
- Redis居然还有比RDB和AOF更强大的持久化方式?
https://cloud.tencent.com/developer/article/1786055
- 骚操作之 持有 ReadOnlySpan 数据
ReadOnlySpan<T> 可以说现在高性能操作的重要基石 其原理有兴趣的同学可以看 2018 的介绍Span<T>文章 其为了保障大家安全使用做了相应的限制 那么有没方法 ...
- git开发规范
- 【Azure 环境】使用az login登录遇见OSError: [WinError -2146893813] : '' 错误
问题描述 使用 az login指令登录,遇见 OS Error: [WinError -2146893813] : '', 在指令中添加 --debug后,输出的错误消息为: urllib3.con ...
- 【Azure 环境】中国区Azure B2C 是否支持手机验证码登录呢?
问题描述 中国区Azure B2C 是否支持手机验证码登录呢? 问题回答 在没有原生 Phone sign-up and sign-in for user flows (中国区不支持,Global A ...
- Dapr v1.13 版本已发布
Dapr是一套开源.可移植的事件驱动型运行时,允许开发人员轻松立足云端与边缘位置运行弹性.微服务.无状态以及有状态等应用程序类型.Dapr能够确保开发人员专注于编写业务逻辑,而不必分神于解决分布式系统 ...
- PaddleOCR 服务化部署(基于PaddleHub Serving)
最近用到百度飞桨的 PaddleOCR,研究了一下PaddleOCR的服务化部署,简单记录一些部署过程和碰到的问题. 基础环境 paddlepaddle 2.5.2 python 3.7 paddle ...
- 基于RocketMQ实现分布式事务(半消息事务)
一.背景 RocketMQ的分布式事务可以称为"半消息事务". 二.原理 2.1原理 RocketMQ是靠半消息机制实现分布式事务: 事务消息:MQ 提供类似 X/Open XA ...
- vite ts 安装 js-cookie 库,vscode找不到类型说明(有波浪线),解决方案
vite ts 安装 js-cookie 库,vscode找不到类型说明(有波浪线),解决方案 先安装库 https://www.npmjs.com/package/js-cookie 再安装类型 h ...
- buu第一页复盘
这里就对之前第一遍没写出来的题目再写一次wp 写在之前 贴一下我的模块文件 from pwn import * from LibcSearcher import * from struct impor ...