题目

多组数据,给定一个\(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. pikachu sql inject 宽字节注入

    宽字节注入原理 什么是宽字节? 如果一个字符的大小是一个字节的,称为窄字节: 如果一个字符的大小是两个字节的,成为宽字节: 像GB2312.GBK.GB18030.BIG5.Shift_JIS等这些编 ...

  2. 鸿蒙开发学习(二)之ArkUI

    目录 UI开发 布局 布局选择 布局位置 组件 容器组件 row.column RelativeContainer 列表 Tabs 子组件 页面路由 GitHub地址,欢迎star HmDemo: 鸿 ...

  3. offline RL | 读读 Decision Transformer

    论文标题:Decision Transformer: Reinforcement Learning via Sequence Modeling,NeurIPS 2021,6 6 7 9 poster( ...

  4. ASP.NET Core MVC应用模型的构建[3]: Controller的收集

    从编程的角度来看,一个MVC应用是由一系列Controller类型构建而成的,所以对于一个代表应用模型的ApplicationModel对象来说,它的核心就是Controllers属性返回的一组Con ...

  5. 【应用服务 App Service】 App Service Rewrite 实例 -- 限制站点的访问

    问题描述 在Azure App Service中,当需要限制某些特殊的情况对其进行访问时候,可以通过IP限制,逻辑代码判断,或者Rewrite规则.通过IP限制则需要知道客户端访问的IP,而通过逻辑代 ...

  6. [C++逆向] 7 变量在内存中的位置和访问方式

    目录 全局变量和局部变量的区别 局部静态变量 有意思的 堆变量 变量类型 作用域 可访问 全局变量 进程作用域 整个进程可访问 静态变量 文件作用域 当前代码文件可访问 局部变量 函数作用域 函数内可 ...

  7. CDC作业历史记录无法删除问题

    背景 数据库开启CDC功能后,每天会生成大量的历史记录,即使达到参数"每个作业的最大历史记录"的阈值后也不会被删除,导致其它作业的历史记录被删除,无法查看以前的执行情况,非常不方便 ...

  8. Java 数组 数据类型默认值

    1 public static void main(String[] args) 2 { 3 int[] arry = new int[4]; //int 默认值0 //浮点型 0.0 4 for(i ...

  9. C++ //常用集合算法 //set_intersection //求俩个容器的交集 //set_union //求两个容器的并集 //set_difference //求两个容器的差集

    1 //常用集合算法 2 //set_intersection //求俩个容器的交集 3 //set_union //求两个容器的并集 4 //set_difference //求两个容器的差集 5 ...

  10. Codeforces Round 923 (Div. 3)(A~F)

    目录 A B C D E F A #include <bits/stdc++.h> #define int long long #define rep(i,a,b) for(int i = ...