本文版权归ljh2000和博客园共有,欢迎转载,但须保留此声明,并给出原文链接,谢谢合作。

本文作者:ljh2000
作者博客:http://www.cnblogs.com/ljh2000-jump/
转载请注明出处,侵权必究,保留最终解释权!

 
Problem Description
The God of sheep decides to pixelate some pictures (i.e., change them into pictures with mosaic). Here's how he is gonna make it: for each picture, he divides the picture into n x n cells, where each cell is assigned a color value. Then he chooses a cell, and checks the color values in the L x L region whose center is at this specific cell. Assuming the maximum and minimum color values in the region is A and B respectively, he will replace the color value in the chosen cell with floor((A + B) / 2).

Can you help the
God of sheep?

 
Input
The first line contains an integer T (T ≤ 5) indicating
the number of test cases. Then T test cases follow.

Each test case begins
with an integer n (5 < n < 800). Then the following n rows describe the
picture to pixelate, where each row has n integers representing the original
color values. The j-th integer in the i-th row is the color value of cell (i, j)
of the picture. Color values are nonnegative integers and will not exceed
1,000,000,000 (10^9).

After the description of the picture, there is an
integer Q (Q ≤ 100000 (10^5)), indicating the number of mosaics.

Then Q
actions follow: the i-th row gives the i-th replacement made by the God of
sheep: xi, yi, Li (1 ≤ xi, yi ≤ n, 1 ≤ Li < 10000, Li is odd). This means the
God of sheep will change the color value in (xi, yi) (located at row xi and
column yi) according to the Li x Li region as described above. For example, an
query (2, 3, 3) means changing the color value of the cell at the second row and
the third column according to region (1, 2) (1, 3), (1, 4), (2, 2), (2, 3), (2,
4), (3, 2), (3, 3), (3, 4). Notice that if the region is not entirely inside the
picture, only cells that are both in the region and the picture are
considered.

Note that the God of sheep will do the replacement one by one
in the order given in the input.

 
Output
For each test case, print a line "Case #t:"(without
quotes, t means the index of the test case) at the beginning.

For each
action, print the new color value of the updated cell.

 
Sample Input
1
3
1 2 3
4 5 6
7 8 9
5
2 2 1
3 2 3
1 1 3
1 2 3
2 2 3
 
Sample Output
Case #1:
5
6
3
4
6
 
 
正解:二维线段树
解题报告:
  又调了一个晚上的题目…
  (每晚留一道题目调不完的debuff...)
  二维线段树相当于是维护了一个矩阵,不妨叫做主线段树和副线段树,那么主线段树上的每个节点都存了一棵副线段树(可以动态开节点呀),那么就没有区别了…
  只是要注意一点,modify了之后显然不能直接merge两个子树,复杂度是线性的...
  直接查询两个子树的这一位,取max/min然后在子树上直接modify即可。
  
 
//It is made by ljh2000
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <ctime>
#include <vector>
#include <queue>
#include <map>
#include <set>
#include <string>
#include <complex>
using namespace std;
typedef long long LL;
const int MAXN = 811;
const int MAXM = 5000011;
int n,m,ju[MAXN][MAXN],X[2],Y[2],cnt,rt,ans,CC;
struct node{ int l,r,ls,rs,maxl,minl,tree; }a[MAXM];
inline int getint(){
int w=0,q=0; char c=getchar(); while((c<'0'||c>'9') && c!='-') c=getchar();
if(c=='-') q=1,c=getchar(); while (c>='0'&&c<='9') w=w*10+c-'0',c=getchar(); return q?-w:w;
} namespace Seg_tree{
inline void build(int &k,int l,int r,int bel){
k=++cnt; a[k].l=l; a[k].r=r; if(l==r) { a[k].minl=a[k].maxl=ju[l][bel]; return ; }
int mid=(l+r)>>1; build(a[k].ls,l,mid,bel); build(a[k].rs,mid+1,r,bel);
a[k].minl=min(a[a[k].ls].minl,a[a[k].rs].minl); a[k].maxl=max(a[a[k].ls].maxl,a[a[k].rs].maxl);
} inline int query_min(int k,int l,int r){
if(Y[0]<=l && r<=Y[1]) return a[k].minl;
int mid=(l+r)>>1;
if(Y[0]>mid) return query_min(a[k].rs,mid+1,r);
else if(Y[1]<=mid) return query_min(a[k].ls,l,mid);
else return min(query_min(a[k].ls,l,mid),query_min(a[k].rs,mid+1,r));
} inline int query_max(int k,int l,int r){
if(Y[0]<=l && r<=Y[1]) return a[k].maxl;
int mid=(l+r)>>1;
if(Y[0]>mid) return query_max(a[k].rs,mid+1,r);
else if(Y[1]<=mid) return query_max(a[k].ls,l,mid);
else return max(query_max(a[k].ls,l,mid),query_max(a[k].rs,mid+1,r));
} inline void modify(int k,int l,int r,int y){
if(l==r) { a[k].minl=a[k].maxl=ans; return ; }
int mid=(l+r)>>1;
if(y<=mid) modify(a[k].ls,l,mid,y); else modify(a[k].rs,mid+1,r,y);
a[k].minl=min(a[a[k].ls].minl,a[a[k].rs].minl); a[k].maxl=max(a[a[k].ls].maxl,a[a[k].rs].maxl);
} inline void update_min(int k,int l,int r,int y){
if(l==r) { a[k].minl=CC; return ; }
int mid=(l+r)>>1;
if(y<=mid) update_min(a[k].ls,l,mid,y); else update_min(a[k].rs,mid+1,r,y);
a[k].minl=min(a[a[k].ls].minl,a[a[k].rs].minl);
} inline void update_max(int k,int l,int r,int y){
if(l==r) { a[k].maxl=CC; return ; }
int mid=(l+r)>>1;
if(y<=mid) update_max(a[k].ls,l,mid,y); else update_max(a[k].rs,mid+1,r,y);
a[k].maxl=max(a[a[k].ls].maxl,a[a[k].rs].maxl);
}
} inline void merge(int &k,node q,node qq){
if(!k) k=++cnt; a[k].maxl=max(q.maxl,qq.maxl); a[k].minl=min(q.minl,qq.minl);
a[k].l=q.l; a[k].r=q.r; if(q.l==q.r) return ;
merge(a[k].ls,a[q.ls],a[qq.ls]);
merge(a[k].rs,a[q.rs],a[qq.rs]);
} inline void build(int &k,int l,int r){
k=++cnt; a[k].l=l; a[k].r=r;
if(l==r) {
Seg_tree::build(a[k].tree,1,n,l);
return;
}
int mid=(l+r)>>1; build(a[k].ls,l,mid); build(a[k].rs,mid+1,r);
merge(a[k].tree,a[ a[a[k].ls].tree ],a[ a[a[k].rs].tree ]);
} inline int query_min(int k,int l,int r){
if(X[0]<=l && r<=X[1]) return Seg_tree::query_min(a[k].tree,1,n);
int mid=(l+r)>>1;
if(X[0]>mid) return query_min(a[k].rs,mid+1,r);
else if(X[1]<=mid) return query_min(a[k].ls,l,mid);
else return min(query_min(a[k].ls,l,mid),query_min(a[k].rs,mid+1,r));
} inline int query_max(int k,int l,int r){
if(X[0]<=l && r<=X[1]) return Seg_tree::query_max(a[k].tree,1,n);
int mid=(l+r)>>1;
if(X[0]>mid) return query_max(a[k].rs,mid+1,r);
else if(X[1]<=mid) return query_max(a[k].ls,l,mid);
else return max(query_max(a[k].ls,l,mid),query_max(a[k].rs,mid+1,r));
} inline void modify(int k,int l,int r,int x,int y){
if(l==r) { Seg_tree::modify(a[k].tree,1,n,y); return ; }
int mid=(l+r)>>1;
if(x<=mid) modify(a[k].ls,l,mid,x,y);
else modify(a[k].rs,mid+1,r,x,y); int lc=a[k].ls,rc=a[k].rs;
int lmin=Seg_tree::query_min(a[lc].tree,a[a[lc].tree].l,a[a[lc].tree].r);
int rmin=Seg_tree::query_min(a[rc].tree,a[a[rc].tree].l,a[a[rc].tree].r);
CC=min(lmin,rmin); Seg_tree::update_min(a[k].tree,a[a[k].tree].l,a[a[k].tree].r,y); int lmax=Seg_tree::query_max(a[lc].tree,a[a[lc].tree].l,a[a[lc].tree].r);
int rmax=Seg_tree::query_max(a[rc].tree,a[a[rc].tree].l,a[a[rc].tree].r);
CC=max(lmax,rmax); Seg_tree::update_max(a[k].tree,a[a[k].tree].l,a[a[k].tree].r,y);
//merge(a[k].tree,a[ a[a[k].ls].tree ],a[ a[a[k].rs].tree ]);
} inline void work(){
int T=getint();
for(int Case=1;Case<=T;Case++) {
printf("Case #%d:\n",Case); n=getint(); for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) ju[i][j]=getint();
for(int i=1;i<=cnt;i++) a[i].tree=a[i].ls=a[i].rs=0; cnt=0; rt=0;
build(rt,1,n); m=getint(); int x,y,z,da,xiao;
while(m--) {
y=getint(); x=getint(); z=getint(); z>>=1;
X[0]=max(x-z,1); X[1]=min(x+z,n);
Y[0]=max(y-z,1); Y[1]=min(y+z,n);
da=query_max(rt,1,n);
xiao=query_min(rt,1,n);
ans=(da+xiao)>>1; printf("%d\n",ans);
Y[0]=Y[1]=y;
modify(rt,1,n,x,y);
}
} } int main()
{
work();
return 0;
}

  

HDU4819 Mosaic的更多相关文章

  1. HDU4819 Mosaic【树套树】

    LINK 题目大意 给你一个\(n*n\)矩阵,每个点有初始权值 q次询问每次把一个矩形的中心节点变成这个矩形中最大值和最小值的平均数 思路 很显然的树套树啊 就是一开始傻逼了没想到怎么去维护这个东西 ...

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

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

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

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

  4. URAL Mosaic(并查集)(欧拉回路)

    Mosaic Time limit: 0.25 secondMemory limit: 64 MB There's no doubt that one of the most important an ...

  5. Mosaic HDU 4819 二维线段树入门题

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

  6. HDU 4819 Mosaic 二维线段树

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

  7. 用opencv画矩形打上马赛克Mosaic

    /*----------------------------------------------------------------------------- *   *   版权声明: *   可以 ...

  8. Mosaic 前端微服务框架

    Mosaic 是一系列的服务.库,集成在一起,定义了组件如何彼此交互,可以用来支持大规模的web 站点开发 一张架构图 说明 尽管上图中的一些组件已经迭代演化了(skipper 的route 配置,上 ...

  9. 镶嵌数据集 Mosaic Dataset 的常见数据组织方式

    镶嵌数据集是ESRI公司推出一种用于管理海量影像数据的数据模型,定义在GeoDatabase数据模型中. 它的常见数据组织方式有两种: 1. 源镶嵌数据集 Source Mosaic Dataset ...

随机推荐

  1. 统计TCP网络连接情况

    #!/bin/bash metric=$1 tmp_file=/tmp/tcp_status.txt /bin/netstat -an|awk '/^tcp/{++S[$NF]}END{for(a i ...

  2. this.$apply()

    chooseVideo(e) { this.fileInfo = {} let that = this wx.chooseVideo({ sourceType: ['album', 'camera'] ...

  3. Lucene索引数计算

    Elasticsearch默认在创建索引结束时得到5个分片及1个副本: 分片是有0-n个副本,“5个分片及1个副本”即“5个分片及5个相应分片副本”:共10个Lucene索引 副本数:指的是“单个分片 ...

  4. PowerPC架构与X86架构

    PowerPC架构 PowerPC是一种精简指令集(RISC)架构的中央处理器(CPU),其基本的设计源自IBM(国际商用机器公司)的POWER(Performance Optimized With ...

  5. python函数回顾:next()

    描述 next() 返回迭代器的下一个项目. 语法 next(iterator[, default]) 参数说明: iterator -- 可迭代对象 default -- 可选,用于设置在没有下一个 ...

  6. 开机提示memory size decreased怎么办?

    ytkah的办公电脑实在是hold不住,win7用2G的内存,基本是在等待中度过的,没有新的只能考虑加格内存了,采购嘛,需走一大堆流程,跟领导请示从其他硬件需求不是很高的电脑那边拔一根内存条吧,小C的 ...

  7. 《Python数据分析》笔记——数据可视化

    数据可视化 matplotlib绘图入门 为了使用matplotlib来绘制基本图像,需要调用matplotlib.pyplot子库中的plot()函数 import matplotlib.pyplo ...

  8. 我的第一个Python小程序

    猜年龄,如果大了提示小点,如果小了,提示大点 涉及的知识点: 1.变量 2.注释 3.接收交互式的输入 4.类型转换 5.while循环 6.if..elif..else多条件分支语句 # Autho ...

  9. Django工作小笔记

    场景一:如果model中字段用CharField,然而你想用数字(类似IntegerField)排序,此时可以用django的extra函数直接调用原生sql的CAST函数即可 Score.objec ...

  10. 剑指offer 面试60题

    面试60题 题目:把n个骰子扔在地上,所有骰子朝上一面的点数之和为s.输入n,打印出s的所有可能的值出现的概率. 解决代码: