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 ...
随机推荐
- 为什么阿里Java规约要求谨慎使用SimpleDateFormat
前言 在阿里Java开发规约中,有强制性的提到SimpleDateFormat 是线程不安全的类 ,在使用的时候应当注意线程安全问题,如下: 其实之前已经介绍过使用JDK1.8的DateTimeFor ...
- python基本输入输出函数与变量类型
7.python具有三个重要的输出输入函数:print(输出)/eval(转换)/input(输入): 8.对于输出函数print函数的具体使用规则如下:(1)输出字符串:print("字符 ...
- Java 代码空间复杂度查看工具
SourceMonitor 下载地址:http://www.campwoodsw.com/sourcemonitor.html
- Python 类型转换指南
一.int型 支持转换为 int 类型的,仅有 float.str.bytes,其他类型均不支持. 1.float -> int会去掉小数点及后面的数值,仅保留整数部分. 2.str -> ...
- 三星 S10 运行 Ubuntu 系统
导读 DeX 是一种模仿桌面操作系统的用户 UI 界面,把支持 DeX 的三星手机用数据线连上外置显示器,用户就可以获得一种类似桌面系统的使用体验. 三星 S8.Note 8.S9.Note 9.S1 ...
- jQuery Validation Engine
<!DOCTYPE HTML> <html> <head> <meta charset="utf-8"> <title> ...
- CNN反向传播算法公式
网络结构(6c-2s-12c-2s): 初始化: \begin{align}\notag W \sim U(- \frac{\sqrt{6}}{\sqrt{n_j+n_{j+1}}} , \frac{ ...
- 六、java基础-单例模式_继承_覆盖_多态
1.单例模式: 1)提出原因 是由gof 也就是四人组提出来的.为了保证jvm中某一类型的java对象永远只有一个,同时也是为了节省内存的开销.因为外面程序可以通过new的方法直接调用类里面的构造方法 ...
- js 用于运行string中的<script>和</script>之间的函数
/** * Created by 炜文 on 2017/2/15. */ var intext = '485222<script> var i=2;var j=2;console.log( ...
- 通过CrawlSpider对招聘网站进行整站爬取(拉勾网实战)
爬虫首先要明确自己要爬取的网站以及内容 进入拉勾网的网站然后看看想要爬取什么内容职位,薪资,城市,经验要求学历要求,全职或者兼职职位诱惑,职位描述提取公司的名称 以及 在拉勾网的url等等 然后在na ...