额,大意,求一个由(x,y,l)的关系所构成的矩形区域的最大值A和最小值B,输出(A+B)/2,并更新成(x,y)的值.
显然是二维线段树,区间查询,单点更新.
写的头疼,一直忽略了第一维也是表示的区间,一直把他搞成一个点,终于过了!!!
一开始开的结构体,直接MLE......
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
#define N 805
#define INF ~0U>>1
typedef pair<int,int>ii;
inline int input()
{
int ret=0;
char c=getchar();
while(c<'0'||c>'9')
c=getchar();
while(c>='0'&&c<='9')
ret=ret*10+c-'0',c=getchar();
return ret;
}
int t,n,map[N][N],q,x1,x2,y1,y2,val,x,y,z,Max,Min;
ii node[N<<2][N<<2];
inline void build_son(int w,int L,int R,int t,int x,int y)
{
if(x==y)
{
Max=-1,Min=INF;
for(int i=L;i<=R;i++)
{
Max=max(Max,map[i][x]),Min=min(Min,map[i][x]);
}
node[w][t]=make_pair(Max,Min);
return;
}
int m=(x+y)>>1;
build_son(w,L,R,t*2,x,m),build_son(w,L,R,t*2+1,m+1,y);
node[w][t]=make_pair(max(node[w][t*2].first,node[w][t*2+1].first),min(node[w][t*2].second,node[w][t*2+1].second));
}
inline void build(int t,int x,int y)
{
build_son(t,x,y,1,1,n);
if(x==y)
return;
int m=(x+y)>>1;
build(t*2,x,m),build(t*2+1,m+1,y);
}
inline void Modefiy_son(int w,int l,int r,int t,int L,int R,int x)
{
if(L==R)
{
/*
以前写的node[w][t]=make_pair(val,val);
......
*/
Max=-1,Min=INF;
for(int i=l;i<=r;i++)
{
Max=max(Max,map[i][x]),Min=min(Min,map[i][x]);
}
node[w][t]=make_pair(Max,Min);
return;
}
int m=(L+R)>>1;
if(x<=m) Modefiy_son(w,l,r,t*2,L,m,x);
else Modefiy_son(w,l,r,t*2+1,m+1,R,x);
node[w][t]=make_pair(max(node[w][t*2].first,node[w][t*2+1].first),min(node[w][t*2].second,node[w][t*2+1].second));
}
inline void Modefiy(int t,int L,int R,int x,int y)
{
Modefiy_son(t,L,R,1,1,n,y);
if(L==R)
return;
int m=(L+R)>>1;
if(x<=m) Modefiy(t*2,L,m,x,y);
else Modefiy(t*2+1,m+1,R,x,y);
}
inline ii query_son(int w,int t,int L,int R,int x,int y)
{
if(L>=x&&R<=y)
{
return node[w][t];
}
int m=(L+R)>>1;
ii a,b,ans;
a=b=make_pair(-1,INF);
if(x<=m) a=query_son(w,t*2,L,m,x,min(m,y));
if(y>m) b=query_son(w,t*2+1,m+1,R,max(m+1,x),y);
ans=make_pair(max(a.first,b.first),min(a.second,b.second));
return ans;
}
inline ii query(int t,int L,int R,int x1,int x2,int y1,int y2)
{
if(L>=x1&&R<=x2)
{
return query_son(t,1,1,n,y1,y2);
}
int m=(L+R)>>1;
ii a,b,ans;
a=b=make_pair(-1,INF);
if(x1<=m) a=query(t*2,L,m,x1,min(m,x2),y1,y2);
if(x2>m) b=query(t*2+1,m+1,R,max(m+1,x1),x2,y1,y2);
ans=make_pair(max(a.first,b.first),min(a.second,b.second));
return ans;
}
int main()
{
//freopen("1.txt","r",stdin);
t=input();
for(int ca=1;ca<=t;ca++)
{
n=input();
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
map[i][j]=input();
build(1,1,n);
q=input();
printf("Case #%d:\n",ca);
while(q--)
{
x=input(),y=input(),z=input();
z=(z-1)/2;
x1=max(1,x-z),y1=max(1,y-z);
x2=min(n,x+z),y2=min(n,y+z);
ii ans=query(1,1,n,x1,x2,y1,y2);
val=ans.first/2+ans.second/2+(ans.first%2+ans.second%2)/2;
printf("%d\n",val);
map[x][y]=val;
Modefiy(1,1,n,x,y);
}
}
return 0;
}