【二維線段樹】hdu 4819 Mosaic

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;
}


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