hdu 4819 Mosaic【二維線段樹】

題目大意:

給出一個矩陣,有一種操作: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;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章