http://acm.hdu.edu.cn/showproblem.php?pid=4819
二维线段树,动态查询(与二维RMQ互补)
/*
hdu 4819 二维线段树
支持动态查询、修改,与二维RMQ互补(只支持静态查询)
套了个模板
*/
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<cstring>
#include<vector>
#include<queue>
#include<set>
#include<map>
#include<algorithm>
#include<sstream>
#define eps 1e-9
#define pi acos(-1)
#define INF 0x7fffffff
#define inf -INF
#define MM 10
#define N 1010
using namespace std;
typedef long long ll;
const int _max = 800 + 10;
struct Nodey{
int l,r;
int Max,Min;
};
int locy[_max],locx[_max];
struct Nodex{
int l,r;
Nodey sty[_max*4];
void build(int i,int _l,int _r){
sty[i].l = _l;
sty[i].r = _r;
sty[i].Max = -INF;
sty[i].Min = INF;
if(_l == _r){
locy[_l] = i;
return;
}
int mid = (_l + _r)/2;
build(i<<1,_l,mid);
build((i<<1)|1,mid+1,_r);
}
int queryMin(int i,int _l,int _r){
if(sty[i].l == _l && sty[i].r == _r)
return sty[i].Min;
int mid = (sty[i].l + sty[i].r)/2;
if(_r <= mid)return queryMin(i<<1,_l,_r);
else if(_l > mid)return queryMin((i<<1)|1,_l,_r);
else return min(queryMin(i<<1,_l,mid),queryMin((i<<1)|1,mid+1,_r));
}
int queryMax(int i,int _l,int _r){
if(sty[i].l == _l && sty[i].r == _r)
return sty[i].Max;
int mid = (sty[i].l + sty[i].r)/2;
if(_r <= mid)return queryMax(i<<1,_l,_r);
else if(_l > mid)return queryMax((i<<1)|1,_l,_r);
else return max(queryMax(i<<1,_l,mid),queryMax((i<<1)|1,mid+1,_r));
}
}stx[_max*4];
int n;
void build(int i,int l,int r){
stx[i].l = l;
stx[i].r = r;
stx[i].build(1,1,n);
if(l == r){
locx[l] = i;
return;
}
int mid = (l+r)/2;
build(i<<1,l,mid);
build((i<<1)|1,mid+1,r);
}
//修改值
void Modify(int x,int y,int val){
int tx = locx[x];
int ty = locy[y];
stx[tx].sty[ty].Min = stx[tx].sty[ty].Max = val;
for(int i = tx;i;i >>= 1)
for(int j = ty;j;j >>= 1){
if(i == tx && j == ty)continue;
if(j == ty){
stx[i].sty[j].Min = min(stx[i<<1].sty[j].Min,stx[(i<<1)|1].sty[j].Min);
stx[i].sty[j].Max = max(stx[i<<1].sty[j].Max,stx[(i<<1)|1].sty[j].Max);
}
else{
stx[i].sty[j].Min = min(stx[i].sty[j<<1].Min,stx[i].sty[(j<<1)|1].Min);
stx[i].sty[j].Max = max(stx[i].sty[j<<1].Max,stx[i].sty[(j<<1)|1].Max);
}
}
}
int queryMin(int i,int x1,int x2,int y1,int y2){
if(stx[i].l == x1 && stx[i].r == x2)
return stx[i].queryMin(1,y1,y2);
int mid = (stx[i].l + stx[i].r)/2;
if(x2 <= mid)return queryMin(i<<1,x1,x2,y1,y2);
else if(x1 > mid)return queryMin((i<<1)|1,x1,x2,y1,y2);
else return min(queryMin(i<<1,x1,mid,y1,y2),queryMin((i<<1)|1,mid+1,x2,y1,y2));
}
int queryMax(int i,int x1,int x2,int y1,int y2){
if(stx[i].l == x1 && stx[i].r == x2)
return stx[i].queryMax(1,y1,y2);
int mid = (stx[i].l + stx[i].r)/2;
if(x2 <= mid)return queryMax(i<<1,x1,x2,y1,y2);
else if(x1 > mid)return queryMax((i<<1)|1,x1,x2,y1,y2);
else return max(queryMax(i<<1,x1,mid,y1,y2),queryMax((i<<1)|1,mid+1,x2,y1,y2));
}
int main(){
#ifndef ONLINE_JUDGE
freopen("input.txt","r",stdin);
#endif // ONLINE_JUDGE
int T;cin>>T;int kase = 1;
while(T--){
scanf("%d",&n);
build(1,1,n);
for(int i = 1;i <= n; ++ i)
for(int j = 1; j <= n; ++ j){
int x;
scanf("%d",&x);
Modify(i,j,x);
}
int Q,r1,c1,r2,c2,L,x,y;
scanf("%d",&Q);
printf("Case #%d:\n",kase++);
while(Q--){
scanf("%d%d%d",&x,&y,&L);
r1 = max(1,x-L/2);
r2 = min(n,x+L/2);
c1 = max(1,y-L/2);
c2 = min(n,y+L/2);
int minn = queryMin(1,r1,r2,c1,c2);
int maxx = queryMax(1,r1,r2,c1,c2);
printf("%d\n",(minn+maxx)/2);
Modify(x,y,(minn+maxx)/2);
}
}
return 0;
}