您的位置:首页 > 大数据 > 人工智能

hdu 4819 Mosaic【二维线段树】

2014-09-30 16:24 330 查看
题目大意:

给出一个矩阵,有一种操作:x,y,l,将(x,y)元素修改为,以(x,y)为中心,尺寸为l*l的矩阵中(min+max)/2。

就是一个裸的二维线段树,一维是普通线段树,二维每个区间都有一个线段树。

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#define L(x) (x)<<1
#define R(x) ((x)<<1)|1
#define N 810
const int INF=0x3f3f3f3f;
using namespace std;
int n;
struct y
{
int l,r,mi,ma;
};
struct x
{
int l,r;
y cy[N*4];
void bulid(int i,int ll,int rr)
{
cy[i].l=ll,cy[i].r=rr,cy[i].mi=INF,cy[i].ma=-INF;
if(ll==rr) return ;
int mid=(ll+rr)/2;
bulid(L(i),ll,mid);
bulid(R(i),mid+1,rr);
}
int queryMin(int i,int ll,int rr)
{
if(ll==cy[i].l&&rr==cy[i].r)
return cy[i].mi;
int mid=(cy[i].l+cy[i].r)/2;
if(rr<=mid) return queryMin(L(i),ll,rr);
else if(ll>mid) return queryMin(R(i),ll,rr);
else return min(queryMin(L(i),ll,mid),queryMin(R(i),mid+1,rr));
}
int queryMax(int i,int ll,int rr)
{
if(ll==cy[i].l&&rr==cy[i].r)
return cy[i].ma;
int mid=(cy[i].l+cy[i].r)/2;
if(rr<=mid) return queryMax(L(i),ll,rr);
else if(ll>mid) return queryMax(R(i),ll,rr);
else return max(queryMax(L(i),ll,mid),queryMax(R(i),mid+1,rr));
}
}cx[N*4];
void Bulid(int i,int l,int r)
{
cx[i].l=l,cx[i].r=r;
cx[i].bulid(1,1,n);
if(l==r) return ;

int mid=(l+r)/2;
Bulid(L(i),l,mid);
Bulid(R(i),mid+1,r);
}
void update_1D(int j,int i,int x,int y,int val)
{
if(y==cx[j].cy[i].l&&y==cx[j].cy[i].r){
if(cx[j].l==cx[j].r)
{
cx[j].cy[i].mi=cx[j].cy[i].ma=val;
}
else{
int mid=(cx[j].l+cx[j].r)/2;
cx[j].cy[i].mi=min(cx[L(j)].cy[i].mi,cx[R(j)].cy[i].mi);
cx[j].cy[i].ma=max(cx[L(j)].cy[i].ma,cx[R(j)].cy[i].ma);
}
}
else
{
int mid=(cx[j].cy[i].l+cx[j].cy[i].r)/2;
if(y<=mid) update_1D(j,L(i),x,y,val);
else update_1D(j,R(i),x,y,val);
cx[j].cy[i].mi=min(cx[j].cy[L(i)].mi,cx[j].cy[R(i)].mi);
cx[j].cy[i].ma=max(cx[j].cy[L(i)].ma,cx[j].cy[R(i)].ma);
}
}
void update_2D(int i,int x,int y,int val)
{
if(cx[i].l==x&&cx[i].r==x)
{
update_1D(i,1,x,y,val);
}
if(cx[i].l==cx[i].r) return ;
int mid=(cx[i].l+cx[i].r)/2;
if(x<=mid) update_2D(L(i),x,y,val);
else update_2D(R(i),x,y,val);
update_1D(i,1,x,y,val);
}
int QueryMin(int i,int x1,int x2,int y1,int y2)
{
if(cx[i].l==x1&&cx[i].r==x2)
return cx[i].queryMin(1,y1,y2);
//if(cx[i].l==cx[i].r) return cx[i].queryMin(1,y1,y2);
int mid=(cx[i].l+cx[i].r)/2;
if(x2<=mid) return QueryMin(L(i),x1,x2,y1,y2);
else if(x1>mid) return QueryMin(R(i),x1,x2,y1,y2);
else return min(QueryMin(L(i),x1,mid,y1,y2),QueryMin(R(i),mid+1,x2,y1,y2));
}
int QueryMax(int i,int x1,int x2,int y1,int y2)
{
if(cx[i].l==x1&&cx[i].r==x2)
return cx[i].queryMax(1,y1,y2);
//if(cx[i].l==cx[i].r) return cx[i].queryMin(1,y1,y2);
int mid=(cx[i].l+cx[i].r)/2;
if(x2<=mid) return QueryMax(L(i),x1,x2,y1,y2);
else if(x1>mid) return QueryMax(R(i),x1,x2,y1,y2);
else return max(QueryMax(L(i),x1,mid,y1,y2),QueryMax(R(i),mid+1,x2,y1,y2));
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("D:/in.txt","r",stdin);
#endif // ONLINE_JUDGE
int T,cas=1;
scanf("%d",&T);
while(T--)
{
scanf("%d",&n);
printf("Case #%d:\n",cas++);
Bulid(1,1,n);
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
{
int a;
scanf("%d",&a);
update_2D(1,i,j,a);
}
int q;
scanf("%d",&q);
for(int i=0;i<q;i++)
{
int x,y,l;
scanf("%d%d%d",&x,&y,&l);
int x1=max(x-l/2,1);
int x2=min(x+l/2,n);
int y1=max(y-l/2,1);
int y2=min(y+l/2,n);
int mi=QueryMin(1,x1,x2,y1,y2);
int ma=QueryMax(1,x1,x2,y1,y2);
int val=(mi+ma)/2;
update_2D(1,x,y,val);
printf("%d\n",val);
}

}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: