题意:给出一个n行n列的矩阵,每次询问一个二维区间,找出区间内最大值和最小值,去它们平均值,然后输出,再插入那个点。
也是裸裸的二维线段树,太渣。。写了好久,更新的那个地方出了问题,第一层树也要找到准确位置才更新,不是准确位置就从下面更新过的树维护上来。。
#include<cstdio>
#include<cstring>
#include<algorithm>
#define ls (k<<1)
#define rs (k<<1|1)
using namespace std;
const int MAXN=810;
const int INF=(1<<30)-1;
int mp[MAXN][MAXN];
struct Sub_Tree
{
int l,r;
int mxval,mival;
int mid()
{
return (l+r)>>1;
}
};
struct Tree
{
int l,r;
Sub_Tree stree[MAXN<<2];
int mid()
{
return (l+r)>>1;
}
}tree[MAXN<<2];
int n;
void pushup(int k,int fa)
{
tree[fa].stree[k].mival=min(tree[fa].stree[ls].mival,tree[fa].stree[rs].mival);
tree[fa].stree[k].mxval=max(tree[fa].stree[ls].mxval,tree[fa].stree[rs].mxval);
}
void pushupfa(int k,int fa)
{
tree[fa].stree[k].mival=min(tree[fa<<1].stree[k].mival,tree[fa<<1|1].stree[k].mival);
tree[fa].stree[k].mxval=max(tree[fa<<1].stree[k].mxval,tree[fa<<1|1].stree[k].mxval);
}
void build_sub(int l,int r,int k,int fa)
{
tree[fa].stree[k].l=l;
tree[fa].stree[k].r=r;
tree[fa].stree[k].mival=INF;
tree[fa].stree[k].mxval=-INF;
if(l==r)
{
return;
}
int mid=tree[fa].stree[k].mid();
build_sub(l,mid,ls,fa);
build_sub(mid+1,r,rs,fa);
pushup(k,fa);
}
void build(int l,int r,int k)
{
tree[k].l=l;
tree[k].r=r;
build_sub(1,n,1,k);
if(l==r)
return;
int mid=tree[k].mid();
build(l,mid,ls);
build(mid+1,r,rs);
}
void update_sub(int pos,int val,int k,int fa)
{
if(tree[fa].stree[k].l==tree[fa].stree[k].r)
{
//printf("fa=%d pos=%d val=%d\n",fa,pos,val);
if(tree[fa].l==tree[fa].r) //第一层相同更新
tree[fa].stree[k].mival=tree[fa].stree[k].mxval=val;
else //第一层不同,从下面已经更新的区间维护上来
pushupfa(k,fa);
return;
}
int mid=tree[fa].stree[k].mid();
if(pos<=mid)
update_sub(pos,val,ls,fa);
else
update_sub(pos,val,rs,fa);
pushup(k,fa); //维护第二层数
}
void update(int pos1,int pos2,int val,int k)
{
if(tree[k].l==tree[k].r)
{
update_sub(pos2,val,1,k); //第一层树的左右区间相同,第一层也是一个要更新的点,更新第二层数的要更新的点的数值
return;
}
int mid=tree[k].mid();
if(pos1<=mid)
update(pos1,pos2,val,ls);
else
update(pos1,pos2,val,rs);
update_sub(pos2,val,1,k); //第一层树的左右区间不同,从下面已经更新的第一层树维护上来
}
int query_submi(int l,int r,int k,int fa)
{
if(tree[fa].stree[k].l>=l&&tree[fa].stree[k].r<=r)
{
//printf("mi:fa=%d l=%d r=%d val=%d\n",fa,tree[fa].stree[k].l,tree[fa].stree[k].r,tree[fa].stree[k].mival);
return tree[fa].stree[k].mival;
}
int mid=tree[fa].stree[k].mid();
if(r<=mid)
return query_submi(l,r,ls,fa);
else if(l>mid)
return query_submi(l,r,rs,fa);
else
{
int t1=query_submi(l,mid,ls,fa);
int t2=query_submi(mid+1,r,rs,fa);
return min(t1,t2);
}
}
int querymi(int l,int r,int x,int y,int k)
{
if(tree[k].l>=l&&tree[k].r<=r)
{
//printf("l=%d r=%d\n",tree[k].l,tree[k].r);
return query_submi(x,y,1,k);
}
int mid=tree[k].mid();
if(r<=mid)
return querymi(l,r,x,y,ls);
else if(l>mid)
return querymi(l,r,x,y,rs);
else
{
int t1=querymi(l,mid,x,y,ls);
int t2=querymi(mid+1,r,x,y,rs);
return min(t1,t2);
}
}
int query_submx(int l,int r,int k,int fa)
{
if(tree[fa].stree[k].l>=l&&tree[fa].stree[k].r<=r)
{
//printf("mx:fa=%d l=%d r=%d val=%d\n",fa,tree[fa].stree[k].l,tree[fa].stree[k].r,tree[fa].stree[k].mxval);
return tree[fa].stree[k].mxval;
}
int mid=tree[fa].stree[k].mid();
if(r<=mid)
return query_submx(l,r,ls,fa);
else if(l>mid)
return query_submx(l,r,rs,fa);
else
{
int t1=query_submx(l,mid,ls,fa);
int t2=query_submx(mid+1,r,rs,fa);
return max(t1,t2);
}
}
int querymx(int l,int r,int x,int y,int k)
{
if(tree[k].l>=l&&tree[k].r<=r)
{
//printf("l=%d r=%d\n",tree[k].l,tree[k].r);
return query_submx(x,y,1,k);
}
int mid=tree[k].mid();
if(r<=mid)
return querymx(l,r,x,y,ls);
else if(l>mid)
return querymx(l,r,x,y,rs);
else
{
int t1=querymx(l,mid,x,y,ls);
int t2=querymx(mid+1,r,x,y,rs);
return max(t1,t2);
}
}
int main()
{
int i,j,t,flag=1;
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
build(1,n,1);
for(i=1;i<=n;i++)
{
for(j=1;j<=n;j++)
{
scanf("%d",&mp[i][j]);
update(i,j,mp[i][j],1);
}
}
int m,x,y,L;
scanf("%d",&m);
printf("Case #%d:\n",flag++);
while(m--)
{
scanf("%d%d%d",&x,&y,&L);
int l=x-L/2;
int r=x+L/2;
int a=y-L/2;
int b=y+L/2;
if(l<1)
l=1;
if(r>n)
r=n;
if(a<1)
a=1;
if(b>n)
b=n;
int ansmi=querymi(l,r,a,b,1);
int ansmx=querymx(l,r,a,b,1);
int ans=(ansmi+ansmx)/2;
printf("%d\n",ans);
update(x,y,ans,1);
}
}
return 0;
}