HDU 4819 二维线段树
13年长春现场赛的G题,赤裸裸的二维线段树,单点更新,区间查询
不过我是第一次写二维的,一开始写T了,原因是我没有好好利用行段,说白一点,还是相当于枚举行,然后对列进行线段树,那要你写二维线段树干嘛
二维就是在每个行段也建一棵树,来代表这个区间的行里的某些列的值
其他操作倒是不难,因为有一维的功底,只是多写一个,刷刷刷就出来了
就是更新操作的时候有点麻烦,up函数不好写,必须先更新底层,复层是区间值,无法先进行更新,然后底层向父层转移也是有点小技巧,因为每个行段点里面的某些列的列端点号肯定是相同的,比如 我dp[1][rt]和dp[2][rt],表示的都是同样的列,只是一个是儿子行,一个是父亲行,父亲行是>儿子行的,所以更新到底层的时候,就往上每次对第一维除2来更新父节点的相关区域即可
还有发现这个不好直接复制,本题是维护最小值和最大值,在建树的时候,直接修改不太好,先把所有的点的最大设置为-inf,最小设置为INF,这样以修改的方式去赋初值,包括之后的修改也是这样。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define lson rt<<1,l,mid
#define rson rt<<1|1,mid+1,r
#define INF 1<<30
using namespace std;
const int N = 810;
int ds[N*3][N*3];
int db[N*3][N*3];
int flag[N*3][N*3];
int n;
int A[N][N];
struct node
{
int mini,maxn;
};
void up(int k,int rt)
{
db[k][rt]=max(db[k][rt<<1],db[k][rt<<1|1]);
ds[k][rt]=min(ds[k][rt<<1],ds[k][rt<<1|1]);
for (int i=(k>>1);i;i>>=1){
db[i][rt]=max(db[i<<1][rt],db[i<<1|1][rt]);
ds[i][rt]=min(ds[i<<1][rt],ds[i<<1|1][rt]);
}
}
void buildc(int k,int rt,int l,int r)
{
db[k][rt]=-INF;
ds[k][rt]=INF;
if (l>=r){
return;
}
int mid=(l+r)>>1;
buildc(k,lson);
buildc(k,rson);
}
void buildr(int rt,int l,int r)
{
buildc(rt,1,1,n);
if (l>=r){
return;
}
int mid=(l+r)>>1;
buildr(lson);
buildr(rson);
}
node queryc(int k,int c1,int c2,int rt,int l,int r)
{
if (c1<=l && r<=c2){
node x;
x.maxn=db[k][rt];
x.mini=ds[k][rt];
return x;
}
int mid=(l+r)>>1;
if (mid<c1){
return queryc(k,c1,c2,rson);
}
else
if (mid>=c2){
return queryc(k,c1,c2,lson);
}
else{
node a=queryc(k,c1,c2,lson);
node b=queryc(k,c1,c2,rson);
node c;
c.mini=min(a.mini,b.mini);
c.maxn=max(a.maxn,b.maxn);
return c;
}
}
node queryr(int r1,int r2,int c1,int c2,int rt,int l,int r)
{
if (r1<=l && r<=r2)
{
return queryc(rt,c1,c2,1,1,n);
}
int mid=(l+r)>>1;
if (r2<=mid){
return queryr(r1,r2,c1,c2,lson);
}
else
if (r1>mid){
return queryr(r1,r2,c1,c2,rson);
}
else{
node a=queryr(r1,r2,c1,c2,lson);
node b=queryr(r1,r2,c1,c2,rson);
node c;
c.maxn=max(a.maxn,b.maxn);
c.mini=min(a.mini,b.mini);
return c;
}
} void fixc(int val,int k,int C,int rt,int l,int r)
{
if (l>=r)
{
db[k][rt]=val;
ds[k][rt]=val;
for (int i=(k>>1);i;i>>=1){
db[i][rt]=max(db[i<<1][rt],db[i<<1|1][rt]);
ds[i][rt]=min(ds[i<<1][rt],ds[i<<1|1][rt]);
}
return;
}
int mid=(l+r)>>1;
if (C<=mid) fixc(val,k,C,lson);
else fixc(val,k,C,rson);
up(k,rt);
}
void fixr(int val,int R,int C,int rt,int l,int r)
{
if (l>=r)
{
fixc(val,rt,C,1,1,n);
return;
}
int mid=(l+r)>>1;
if (R<=mid) fixr(val,R,C,lson);
else fixr(val,R,C,rson);
}
int main()
{
int t,kase=0;
scanf("%d",&t);
while (t--)
{
scanf("%d",&n);
buildr(1,1,n);
for (int i=1;i<=n;i++){
for (int j=1;j<=n;j++){
scanf("%d",&A[i][j]);
fixr(A[i][j],i,j,1,1,n);
}
} int Q,L,R,S;
scanf("%d",&Q);
printf("Case #%d:\n",++kase);
int r1,r2,c1,c2;
while (Q--)
{
scanf("%d%d%d",&L,&R,&S);
r1=max(L-S/2,1);
r2=min(L+S/2,n);
c1=max(R-S/2,1);
c2=min(R+S/2,n);
node ans=queryr(r1,r2,c1,c2,1,1,n);
int ret=(ans.maxn+ans.mini)/2;
printf("%d\n",ret);
fixr(ret,L,R,1,1,n);
}
}
return 0;
}
HDU 4819 二维线段树的更多相关文章
- hdu 4819 二维线段树模板
/* HDU 4819 Mosaic 题意:查询某个矩形内的最大最小值, 修改矩形内某点的值为该矩形(Mi+MA)/2; 二维线段树模板: 区间最值,单点更新. */ #include<bits ...
- Mosaic HDU 4819 二维线段树入门题
Mosaic Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 102400/102400 K (Java/Others)Total S ...
- HDU 4819 Mosaic(13年长春现场 二维线段树)
HDU 4819 Mosaic 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4819 题意:给定一个n*n的矩阵,每次给定一个子矩阵区域(x,y,l) ...
- HDU 4819 Mosaic (二维线段树)
Mosaic Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 102400/102400 K (Java/Others)Total S ...
- HDU 4819 Mosaic --二维线段树(树套树)
题意: 给一个矩阵,每次查询一个子矩阵内的最大最小值,然后更新子矩阵中心点为(Max+Min)/2. 解法: 由于是矩阵,且要求区间最大最小和更新单点,很容易想到二维的线段树,可是因为之前没写过二维的 ...
- HDU 4819 Mosaic 二维线段树
Mosaic Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://acm.hust.edu.cn/vjudge/contest/view.action ...
- HDU 4819 Mosaic (二维线段树&区间最值)题解
思路: 二维线段树模板题,马克一下,以后当模板用 代码: #include<cstdio> #include<cmath> #include<cstring> #i ...
- HDU 4819 Mosaic 【二维线段树】
题目大意:给你一个n*n的矩阵,每次找到一个点(x,y)周围l*l的子矩阵中的最大值a和最小值b,将(x,y)更新为(a+b)/2 思路:裸的二维线段树 #include<iostream> ...
- HDU 1823 Luck and Love(二维线段树)
之前只知道这个东西的大概概念,没具体去写,最近呵呵,今补上. 二维线段树 -- 点更段查 #include <cstdio> #include <cstring> #inclu ...
随机推荐
- 使用SourceTree的注意事项
1.我使用SourceTree时,使用的下面的配置全局忽略: *~ .DS_Store xcuserdata 2. 远程仓库的url路径不要使用域名,而应该使用ip地址.否则会显示“这是一个无效的ur ...
- python对文件中光标的操作迭代器
seek() 默认从文件开头开始.seek(10) seek(10,1) 需要以b的模式读取文件,从相对位置进行移动光标 seek(-3,2) 倒着移动光标的模式 例如: f= open( ...
- 2020 NUC 19级第一次训练赛
感染(low) Description n户人家住在一条直线上,从左往右依次编号为1,2,...,n.起初,有m户人家感染了COVID-19,而接下来的每天感染的人家都会感染他家左右两家的人,问t天后 ...
- 基于IntelliJ IDEA的代码评审插件 Code Review Plugin
一.阿里规范公约 1.左上角 File -> Settings -> Plugins -> 搜索:Alibaba Java Coding Guidelines,安装插件并重启IDEA ...
- 「NOIP2015」运输计划
传送门 Luogu 解题思路 首先这题可以直接二分答案,然后我们每次都把属于长度大于二分值的路径上的边标记一次,表示选这条边可以优化几条路径. 然后我们显然是要选一条覆盖次数等于需要覆盖的路径数并且长 ...
- redis提供的持久化机制(rdb,aof)
Redis提供的持久化机制 Redis是一种面向“key-value”类型数据的分布式NoSQL数据库系统,具有高性能.持久存储.适应高并发应用场景等优势.它虽然起步较晚,但发展却十分迅速. 近日,R ...
- WebEx如何录制电脑内的声音
WebEx如何录制电脑内的声音 事情是这样的,我需要参加一个网络课程,视频讲课的,但是呢,又因为自己白天需要干别的事,就想着怎么把视频录下来晚上回去看,找了WebEx录屏软件,尝试了下,录屏听 ...
- MyEclipse插件github安装使用
MyEclipse插件github安装使用 网络上的介绍一堆堆的,但是自己尝试了下,发现问题很多,就动手做个教程. 大纲 1.git客户端安装 2.ssh配置 3.egit安装配置 4.参考资料 ...
- 命令打开java控制面板
运行一些java程序时,会提示java安全阻止,需要手动运行,java7一起更改安全级别为“中”就可以了,java8需要配置信任网站 . 这些操作都需要在java控制面板进行,经常会出现无法在控制面板 ...
- R 《回归分析与线性统计模型》page93.6
rm(list = ls()) #数据处理 library(openxlsx) library(car) library(lmtest) data = read.xlsx("xiti4.xl ...