HDU 4819 Mosaic --二维线段树(树套树)
题意: 给一个矩阵,每次查询一个子矩阵内的最大最小值,然后更新子矩阵中心点为(Max+Min)/2.
解法: 由于是矩阵,且要求区间最大最小和更新单点,很容易想到二维的线段树,可是因为之前没写过二维的线段树,所以没跳出来。后来熟悉了一下,原来很多细节地方都没有考虑到。
这里build,update,query都分为两个函数,第一个为Y轴的(sub_update),第二个为X轴的(update),不仅每个sub_update或sub_build后面要加Y轴的pushup函数,而且每个update或build函数最后也要进行pushup,只不过是X轴的pushup,写成 sub_build(rt,-1,1,n,1) 或 sub_update(rt,-1,1,n,1);
二维线段树就是这里比较费解一点,我感觉, 其他地方还比较好理解。
代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#define Mod 1000000007
#define lll __int64
using namespace std;
#define N 100007 struct sub_seg{
lll maxi,mini;
}; struct seg{
sub_seg st[<<];
}tt[<<];
int n;
lll Max,Min; void pushup(int xrt,int rt)
{
tt[xrt].st[rt].maxi = max(tt[xrt].st[rt<<].maxi,tt[xrt].st[rt<<|].maxi);
tt[xrt].st[rt].mini = min(tt[xrt].st[rt<<].mini,tt[xrt].st[rt<<|].mini);
} void sub_build(int xrt,int posY,int l,int r,int rt)
{
if(l == r)
{
if(posY != -)
{
scanf("%I64d",&tt[xrt].st[rt].maxi);
tt[xrt].st[rt].mini = tt[xrt].st[rt].maxi;
}
else
{
tt[xrt].st[rt].maxi = max(tt[xrt<<].st[rt].maxi,tt[xrt<<|].st[rt].maxi);
tt[xrt].st[rt].mini = min(tt[xrt<<].st[rt].mini,tt[xrt<<|].st[rt].mini);
}
return;
}
int mid = (l + r) >> ;
sub_build(xrt,posY, l,mid, *rt);
sub_build(xrt,posY, mid+,r, *rt+);
pushup(xrt,rt); //pushup Y
} void build(int l, int r, int rt)
{
if(l == r)
{
sub_build(rt,l,,n,);
return;
}
int mid = (l + r) >> ;
build(l,mid,*rt);
build(mid+,r,*rt+);
sub_build(rt,-,,n,); //pushup X
} void sub_update(int xrt,int pos,int y,int l,int r,int val,int rt)
{
if(l == r)
{
if(pos!=-)
tt[xrt].st[rt].maxi = tt[xrt].st[rt].mini = val;
else
{
tt[xrt].st[rt].maxi = max(tt[xrt<<].st[rt].maxi,tt[xrt<<|].st[rt].maxi);
tt[xrt].st[rt].mini = min(tt[xrt<<].st[rt].mini,tt[xrt<<|].st[rt].mini);
}
return;
}
int mid = (l+r) >> ;
if(y <= mid) sub_update(xrt, pos, y, l,mid, val, rt<<) ;
else sub_update(xrt, pos, y, mid+,r, val, rt<<|) ;
pushup(xrt,rt); //pushup Y维
} void update(int x,int y,int l,int r,int val,int rt) //单点更新
{
if(l == r)
{
sub_update(rt,l,y,,n,val,);
return;
}
int mid = (l+r) >> ;
if(x<=mid) update(x,y, l,mid, val, rt<<);
else update(x,y, mid+,r, val, rt<<|);
sub_update(rt,-,y,,n,val,); //pushup X维
} void sub_query(int xrt,int aa,int bb,int l,int r,int rt)
{
if(aa <= l && bb >= r)
{
Max = max(Max,tt[xrt].st[rt].maxi);
Min = min(Min,tt[xrt].st[rt].mini);
return;
}
int mid = (l+r)>>;
if(aa<=mid) sub_query(xrt,aa,bb,l,mid, rt<<);
if(bb>mid) sub_query(xrt,aa,bb,mid+,r, rt<<|);
} void query(int l,int r,int aa,int bb,int L1,int R1,int rt)
{
if(aa <= l && bb >= r)
{
sub_query(rt,L1,R1,,n,);
return;
}
int mid = (l+r)>>;
if(aa <= mid) query(l,mid,aa,bb,L1,R1, rt<<);
if(bb > mid) query(mid+,r,aa,bb,L1,R1, rt<<|);
} int main()
{
int t,i,j,m,x,y,L,cs = ;
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
build(,n,);
scanf("%d",&m);
printf("Case #%d:\n",cs++);
while(m--)
{
scanf("%d%d%d",&x,&y,&L);
int Lx = max(,x-L/);
int Ly = max(,y-L/);
int Rx = min(n,x+L/);
int Ry = min(y+L/,n);
Max = -, Min = Mod;
query(,n,Lx,Rx,Ly,Ry,);
lll mid = (Max+Min)/2LL;
printf("%I64d\n",mid);
update(x,y,,n,mid,);
}
}
return ;
}
HDU 4819 Mosaic --二维线段树(树套树)的更多相关文章
- HDU 4819 Mosaic 二维线段树
Mosaic Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://acm.hust.edu.cn/vjudge/contest/view.action ...
- UVALive 6709 - Mosaic 二维线段树
题目链接 给一个n*n的方格, 每个方格有值. 每次询问, 给出三个数x, y, l, 求出以x, y为中心的边长为l的正方形内的最大值与最小值, 输出(maxx+minn)/2, 并将x, y这个格 ...
- 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 (二维线段树&区间最值)题解
思路: 二维线段树模板题,马克一下,以后当模板用 代码: #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 4819 二维线段树模板
/* HDU 4819 Mosaic 题意:查询某个矩形内的最大最小值, 修改矩形内某点的值为该矩形(Mi+MA)/2; 二维线段树模板: 区间最值,单点更新. */ #include<bits ...
- HDU 4819 二维线段树
13年长春现场赛的G题,赤裸裸的二维线段树,单点更新,区间查询 不过我是第一次写二维的,一开始写T了,原因是我没有好好利用行段,说白一点,还是相当于枚举行,然后对列进行线段树,那要你写二维线段树干嘛 ...
- HDU 1823 Luck and Love(二维线段树)
之前只知道这个东西的大概概念,没具体去写,最近呵呵,今补上. 二维线段树 -- 点更段查 #include <cstdio> #include <cstring> #inclu ...
随机推荐
- dbcp 1.4 底层连接断开时内存泄露bug
在dbcp 1.4中,如果底层的连接已经与数据库断开了,此时dbcp 1.4的实现并不释放内部连接,虽然早已提供了removeAbandoned和removeAbandonedTimeout参数,但是 ...
- Selenium&EmguCV实现爬虫图片识别
概述 爬虫需要抓取网站价格,与一般抓取网页区别的是抓取内容是通过AJAX加载,并且价格是通过CSS背景图片显示的. 每一个数字对应一个样式,如'p_h57_5' .p_h57_5 { backgrou ...
- 可怜的js居然没有块级作用域
js中在一个函数中定义一个for循环:for(var i=0;i<5;i++) 其中的i并不会随着for循环的结束就销毁,i会一直存在该函数中,这就是js和其他语言的区别,也就是js没有块级作用 ...
- 生理周期(c++实现)
描述:人生来就有三个生理周期,分别为体力.感情和智力周期,它们的周期长度为23 天. 28 天和33 天.每一个周期中有一天是高峰.在高峰这天,人会在相应的方面表现出色.例如,智力周期的高峰,人会思维 ...
- jQuery UI resizble、draggable的div包含iframe导致缩放和拖拽的不平滑解决方法
前言 不仅仅是jQuery UI resizble的div包含iframe会导致缩放的不平滑,draggable也会出现包含iframe会导致拖放的不平滑,但是因为jQuery UI有为draggab ...
- MongoDB整合Spring
1.环境 Jdk:1.6.0_10-rc2 Spring3.1.2 下载 依赖jar文件: 2.相关配置 ①.Spring配置文件 <?xml version="1.0" ...
- android 事件
package com.example.yanlei.my2; import android.app.Activity; import android.content.Context; import ...
- 网站防止CC攻击的方法
CC攻击(Challenge Collapsar)是DDOS(分布式拒绝服务)的一种,也是一种常见的网站攻击方法,攻击者通过代理服务器或者肉鸡向向受害主机不停地发大量数据包,造成对方服务器资源耗尽,一 ...
- SharePoint 门户添加内网域名
原理:在DNS服务器上,添加一条SharePoint门户所在主机的别名,当我们在浏览器里访问这个别名的时候,会自动到Dns去解析,解析出来这台主机,从而访问到我们的SharePoint门户. 1.打开 ...
- sql动态insert向varchar(MAX)中写入据的问题
sql动态insert向varchar(MAX)中写入据的问题,在写入时出现列无效.后来发现,varchar要加''两个,号才可以 SET @SQL='INSERT INTO '+@TabName+' ...