无论是线段树还是树状数组维护最大值最小值的时候一定要注意,如果有修改操作的话,这个最小值和最大值的更新一定不能由原来的和修改的值得到,一定要重新查询一次,否则可能出现当前最小值是原来的未修改值,但事实上若修改了,此最小值不存在了。此题线段树套线段树,写的代码有点挫了。

#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<string>
#include<set>
#include<algorithm>
#include<vector>
#include<queue>
#include<list>
#include<cmath>
#include<cstring>
#include<map>
#include<stack>
using namespace std;
#define INF 0x3f3f3f3f
#define maxn 805
#define ull unsigned long long
#define ll long long
#define hashmod 99999839
#define mod 7
#define repe(x,y,i) for(i=x;i<=y;++i)
#define repne(x,y,i) for(i=x;i<y;++i)
#define MAX(x,y) (x) < (y) ? (y) : (x);
#define MIN(x,y) (x) < (y) ? (x) : (y);
int rson[maxn<<][],nex[maxn<<],lenr,lenc,rootr;
int cson[(maxn*maxn)<<][],mi[(maxn*maxn)<<],ma[(maxn*maxn)<<];
int a[maxn][maxn],n,ls,rs,fa,x,y,z;
int cx,cy,rx,ry;
inline void pushup(int o){
ls = cson[o][],rs = cson[o][];
mi[o] = MIN(mi[ls],mi[rs]);
ma[o] = MAX(ma[ls],ma[rs]);
}
void find(int o){
int l = ,r = n,mid = (l + r) >> ;
while(l < r){
if(mid < x) o = cson[o][],l = mid + ;
else o = cson[o][],r = mid;
mid = (l + r) >> ;
}
x = mi[o],y = ma[o];
}
int buildc(int l,int r){
int o = lenc;
lenc++;
if(l == r){//其最小,最大值可由行树的左右子树的根指向的列树中得到
if(rx == ry) mi[o] = ma[o] = a[rx][l];//如果是同一行则直接得到
else{
mi[o] = INF,ma[o] = -;
ls = nex[rson[fa][]],rs = nex[rson[fa][]];
x = l,y = r;
find(ls);
mi[o] = MIN(mi[o],x);
ma[o] = MAX(ma[o],y);
x = l,y = r;
find(rs);
mi[o] = MIN(mi[o],x);
ma[o] = MAX(ma[o],y);
}
cson[o][] = cson[o][] = -;
return o;
}
int mid = (l + r) >> ;
cson[o][] = buildc(l,mid),cson[o][] = buildc(mid+,r),pushup(o);
return o;
}
int buildr(int l,int r){
int o = lenr;
lenr++;
if(l == r){
rson[o][] = rson[o][] = -,fa = o,rx = l,ry = r;
nex[o] = buildc(,n);
return o;
}
int mid = (l + r) >> ;
rson[o][] = buildr(l,mid),rson[o][] = buildr(mid+,r),fa = o,rx = l,ry = r;
nex[o] = buildc(,n);
return o;
}
void queryc(int o,int l,int r){
if(r < cx || l > cy) return;
if(l >= cx && r <= cy){x = MIN(x,mi[o]);y = MAX(y,ma[o]);return;}
int mid = (l + r) >> ;
queryc(cson[o][],l,mid),queryc(cson[o][],mid+,r);
}
void queryr(int o,int l,int r){
if(r < rx || l > ry) return;
if(l >= rx && r <= ry){ queryc(nex[o],,n);return;}
int mid = (l + r) >> ;
queryr(rson[o][],l,mid),queryr(rson[o][],mid+,r);
}
void updatec(int o,int l,int r){
if(l == r){
if(rx == ry) mi[o] = ma[o] = z;
else {
mi[o] = INF,ma[o] = -;
ls = nex[rson[fa][]],rs = nex[rson[fa][]];
int tx = x,ty = y;
x = l,y = r;
find(ls);
mi[o] = MIN(mi[o],x);
ma[o] = MAX(ma[o],y);
x = l,y = r;
find(rs);
mi[o] = MIN(mi[o],x);
ma[o] = MAX(ma[o],y);
x = tx,y = ty;
}
return;
}
int mid = (l + r) >> ;
if(mid >= y) updatec(cson[o][],l,mid);
else updatec(cson[o][],mid+,r);
pushup(o);
}
void updater(int o,int l,int r){
if(l == r){rx = ry = l,fa = o,updatec(nex[o],,n);return;}
int mid = (l + r) >> ;
if(mid >= x) updater(rson[o][],l,mid);
else updater(rson[o][],mid+,r);
rx = l,ry = r,fa = o;
updatec(nex[o],,n);
}
int main(){
freopen("a.in","r",stdin);
freopen("b.out","w",stdout);
int q,t = ,T;
scanf("%d",&T);
register int i,j;
while(T--){
scanf("%d",&n);
repe(,n,i) repe(,n,j) scanf("%d",&a[i][j]);
lenr = lenc = ;
rootr = buildr(,n);
scanf("%d",&q);
printf("Case #%d:\n",++t);
repe(,q,i){
scanf("%d%d%d",&x,&y,&z);
rx = x - (z>>),cx = y - (z>>),ry = x + (z>>),cy = y + (z>>);
if(rx <= ) rx = ;if(cx <= ) cx = ;if(ry > n) ry = n;if(cy > n) cy = n;
int tx = x,ty = y;
x = INF,y = -,queryr(rootr,,n),z = (x + y) >> ,printf("%d\n",z);
x = tx,y = ty,updater(rootr,,n);
}
}
return ;
}

hdu 4819 Mosaic的更多相关文章

  1. HDU 4819 Mosaic(13年长春现场 二维线段树)

    HDU 4819 Mosaic 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4819 题意:给定一个n*n的矩阵,每次给定一个子矩阵区域(x,y,l) ...

  2. HDU 4819 Mosaic D区段树

    连接:pid=4819">http://acm.hdu.edu.cn/showproblem.php?pid=4819 意:给出一个800×800下面的矩阵.每次更新一个点的值为以这个 ...

  3. HDU 4819 Mosaic (二维线段树)

    Mosaic Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 102400/102400 K (Java/Others)Total S ...

  4. HDU 4819 Mosaic 二维线段树

    Mosaic Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://acm.hust.edu.cn/vjudge/contest/view.action ...

  5. hdu 4819 Mosaic 树套树 模板

    The God of sheep decides to pixelate some pictures (i.e., change them into pictures with mosaic). He ...

  6. HDU 4819 Mosaic --二维线段树(树套树)

    题意: 给一个矩阵,每次查询一个子矩阵内的最大最小值,然后更新子矩阵中心点为(Max+Min)/2. 解法: 由于是矩阵,且要求区间最大最小和更新单点,很容易想到二维的线段树,可是因为之前没写过二维的 ...

  7. HDU 4819 Mosaic (二维线段树&区间最值)题解

    思路: 二维线段树模板题,马克一下,以后当模板用 代码: #include<cstdio> #include<cmath> #include<cstring> #i ...

  8. HDU 4819 Mosaic 【二维线段树】

    题目大意:给你一个n*n的矩阵,每次找到一个点(x,y)周围l*l的子矩阵中的最大值a和最小值b,将(x,y)更新为(a+b)/2 思路:裸的二维线段树 #include<iostream> ...

  9. hdu 4819 二维线段树模板

    /* HDU 4819 Mosaic 题意:查询某个矩形内的最大最小值, 修改矩形内某点的值为该矩形(Mi+MA)/2; 二维线段树模板: 区间最值,单点更新. */ #include<bits ...

随机推荐

  1. Can't locate ExtUtils/MakeMaker.pm in @INC

    Can't locate ExtUtils/MakeMaker.pm in @INC 解决办法:yum install perl-devel

  2. vue路由导航守卫及前置后置钩子函数参数详解

    首先构建一个测试demo如下图: 接着来探讨路由配置界面 import Vue from 'vue' import Router from 'vue-router' // import HelloWo ...

  3. 入门Promise的用法

    new Promise(function(resolve,reject){ resolve(); //数据处理完成 reject(); //数据处理出错 }).then(function A(){ / ...

  4. LibreOJ #109. 并查集

    题目描述 这是一道模板题. 维护一个 nnn 点的无向图,支持: 加入一条连接 uuu 和 vvv 的无向边 查询 uuu 和 vvv 的连通性 由于本题数据较大,因此输出的时候采用特殊的输出方式:用 ...

  5. 大数据开发学习之构建Hadoop集群-(0)

    有多种方式来获取hadoop集群,包括从其他人获取或是自行搭建专属集群,抑或是从Cloudera Manager 或apach ambari等管理工具来构建hadoop集群等,但是由自己搭建则可以了解 ...

  6. core下的routelink

    core mvc中 routelink返回和 framework mvc中返回的不一样,core中返回 IHtmlContent, 而 fw 中返回 MvcHtmlString 在写分页方法中用到了r ...

  7. C++中:点运算符和箭头运算符的区别

    点运算符用于获取对象成员: 箭头运算符用于获取指针指向的对象的成员: 例如: std::string s1 = "string"; std::string *p = &s1 ...

  8. Ubuntu 18的网络配置

    包括Ubuntu 18.04和18.10,设置为静态IP及DNS. sudo vim /etc/netplan/50-cloud-init.yaml network: ethernets: enp4s ...

  9. spring注解开发-声明式事务(源码)

    1. 环境搭建与测试 1)导入相关依赖 数据源.数据库驱动.Spring-jdbc模块 <dependency> <groupId>org.springframework< ...

  10. 任务备忘(已经完成):用python写一个格式化xml字符串的程序

    功能: 1.将xml中多余的空格,换行符去掉,让xml字符串变成一行. 2.将xml中添加缩进,使用print能正确打印添加缩进后的字符串. 思路: 采用正则表达式来判断xml中字符串的类型: 1.文 ...