hdu 4819 二维线段树点更新

来源:互联网 发布:淘宝非法交易如何退货 编辑:程序博客网 时间:2024/05/22 07:57

题意:

算一个子矩形内的最大和最小的平均值,并将该平均值更新到该子矩形的中心(该矩形的边为奇数)

解题思路:

利用二维线段树的点更新和query即可


注意:

二维线段树的在点更新时,需先更新局部的子区间,然后更新全局区间


//原版#include <stdio.h>#include <string.h>#include <stdlib.h>#define MAXN0 801#define INF 1<<30int max(int aa,int bb);int min(int aa,int bb);struct node1{    int yL,yR;    int minV,maxV;    void setLR(int aa,int bb){        yL = aa;        yR = bb;        //minV = cc;        //maxV = dd;    }    void setVV(int aa,int bb){        minV = min(aa,bb);        maxV = max(aa,bb);    }    bool equal(int aa,int bb){        if(yL==aa&&yR==bb){            return true;        }        return false;    }    };struct node2{    int xL,xR;    void set(int aa,int bb){        xL = aa;        xR = bb;    }    node1 subTR[MAXN0<<2];};node2 TR[MAXN0<<2];int mat[MAXN0][MAXN0];int maxF,minF;int max(int aa,int bb){    return aa>bb?aa:bb;}int min(int aa,int bb){    return aa<bb?aa:bb;}void buildsubTR(int ind1,int ind2,int L,int R){    TR[ind1].subTR[ind2].setLR(L, R);    TR[ind1].subTR[ind2].maxV =0;    TR[ind1].subTR[ind2].minV = INF;    if(L==R){        //TR[ind1].subTR[ind2].setVV(mat[TR[ind1].xR][R],mat[TR[ind1].xR][R]);        return;    }    int mid = (L+R)>>1;    buildsubTR(ind1,ind2<<1,L,mid);    buildsubTR(ind1, (ind2<<1)+1, mid+1,R);    // TR[ind1].subTR[ind2].minV = min(TR[ind1].subTR[ind2<<1].minV, TR[ind1].subTR[(ind2<<1)+1].minV);    //  TR[ind1].subTR[ind2].maxV = max(TR[ind1].subTR[ind2<<1].maxV, TR[ind1].subTR[(ind2<<1)+1].maxV);}void buildTR(int ind,int L,int R,int L1,int R1){    TR[ind].set(L, R);    buildsubTR(ind, 1, L1,R1);    if(L==R){        // buildsubTR(ind, 1, L1,R1);        return;    }    int mid = (L+R)>>1;    buildTR(ind<<1,L,mid,L1,R1);    buildTR((ind<<1)+1,mid+1,R,L1,R1);    TR[ind].subTR[1].minV = min(TR[ind<<1].subTR[1].minV, TR[(ind<<1)+1].subTR[1].minV);    TR[ind].subTR[1].maxV = max(TR[ind<<1].subTR[1].maxV, TR[(ind<<1)+1].subTR[1].maxV);    }void Querysub(int ind1,int ind2,int L2,int R2){    if(TR[ind1].subTR[ind2].equal(L2,R2)){        minF = min(minF,TR[ind1].subTR[ind2].minV);        maxF = max(maxF,TR[ind1].subTR[ind2].maxV);        return;    }    //int mid;        if(TR[ind1].subTR[ind2].yL!=TR[ind1].subTR[ind2].yR){                int      mid = (TR[ind1].subTR[ind2].yL+TR[ind1].subTR[ind2].yR)>>1;        if(mid>=R2){            Querysub(ind1, ind2<<1, L2, R2);        }        else if(mid<L2){            Querysub(ind1, (ind2<<1)+1, L2, R2);        }        else {            Querysub(ind1, ind2<<1, L2, mid);            Querysub(ind1, (ind2<<1)+1, mid+1, R2);        }    }}void Query(int ind1,int L1,int R1,int L2,int R2){    if(TR[ind1].xL==L1&&TR[ind1].xR==R1){        Querysub(ind1,1,L2,R2);        return;    }        if(TR[ind1].xL!=TR[ind1].xR){        int mid = (TR[ind1].xL+TR[ind1].xR)>>1;        if(mid>=R1){            Query(ind1<<1, L1, R1, L2,R2);        }        else if(mid<L1){            Query((ind1<<1)+1,L1,R1,L2,R2);        }        else {            Query(ind1<<1, L1, mid, L2, R2);            Query((ind1<<1)+1, mid+1, R1, L2, R2);        }    }}void updatesub(int ind1,int ind2,int x,int y,int upd){    if(TR[ind1].subTR[ind2].equal(y,y)){        if(TR[ind1].xL==TR[ind1].xR){            TR[ind1].subTR[ind2].setVV(upd, upd);        }        else {            TR[ind1].subTR[ind2].minV = min(TR[(ind1<<1)+1].subTR[(ind2)].minV,TR[ind1<<1].subTR[(ind2)].minV);            TR[ind1].subTR[ind2].maxV = max(TR[ind1<<1].subTR[(ind2)].maxV, TR[(ind1<<1)+1].subTR[(ind2)].maxV);        }        return;    }    int mid = (TR[ind1].subTR[ind2].yL+TR[ind1].subTR[ind2].yR)>>1;    if(mid>=y){        updatesub(ind1, ind2<<1, x,y, upd);    }    else{        updatesub(ind1, (ind2<<1)+1, x, y, upd);    }    TR[ind1].subTR[ind2].minV = min(TR[ind1].subTR[ind2<<1].minV, TR[ind1].subTR[(ind2<<1)+1].minV);    TR[ind1].subTR[ind2].maxV = max(TR[ind1].subTR[ind2<<1].maxV, TR[ind1].subTR[(ind2<<1)+1].maxV);    }void update(int ind1,int x,int y,int upd){    if(TR[ind1].xL==x&&TR[ind1].xR==x){        updatesub(ind1, 1,x, y, upd);        return;    }        int mid = (TR[ind1].xL+TR[ind1].xR)>>1;    if(mid>=x){        update(ind1<<1, x, y, upd);    }    else {        update((ind1<<1)+1, x, y, upd);    }    updatesub(ind1, 1, x,y, upd);    TR[ind1].subTR[1].minV = min(TR[ind1<<1].subTR[1].minV, TR[(ind1<<1)+1].subTR[1].minV);    TR[ind1].subTR[1].maxV = max(TR[ind1<<1].subTR[1].maxV, TR[(ind1<<1)+1].subTR[1].maxV);}void prepro(int n){    //    for(int i=1;i<=n;++i){    //        for(int j=1;j<=n;++j){    //            if(j==1){    //                minmat[j][i] = maxmat[j][i] = mat[j][i];    //            }    //            else{    //                minmat[j][i] = min(minmat[j-1][i],);    //            }    //        }    //    }}int main(){    int T,n,Q,xi,yi,Li,L1,R1,L2,R2,tmp,ans;    int cas = 0;    scanf("%d",&T);    while(T--){        scanf("%d",&n);        buildTR(1,1,n,1,n);                for(int i=1;i<=n;++i){            for(int j=1;j<=n;++j){                scanf("%d",&mat[i][j]);                update(1, i, j, mat[i][j]);            }        }        //prepro(n);        printf("Case #%d:\n",++cas);        scanf("%d",&Q);        while(Q--){            scanf("%d%d%d",&xi,&yi,&Li);            tmp = Li/2;            L1 = xi - tmp;            if(L1<=0)L1 = 1;            R1 = xi + tmp;            if(R1>n)R1 = n;            L2 = yi - tmp;            if(L2<=0)L2 = 1;            R2 = yi+tmp;            if(R2>n)R2 = n;            maxF = 0;            minF = INF;            Query(1,L1,R1,L2,R2);            ans = (maxF+minF)/2;            printf("%d\n",ans);            if(mat[xi][yi]!=ans){                update(1,xi,yi,ans);                mat[xi][yi] = ans;            }        }    }    return 0;}//改进//总结:且先解决子问题,然后总问题即可解决#include <stdio.h>#include <string.h>#include <stdlib.h>#define MAXN0 801#define INF 1<<30int max(int aa,int bb);int min(int aa,int bb);struct node1{    int yL,yR;    int minV,maxV;    void setLR(int aa,int bb){        yL = aa;        yR = bb;        //minV = cc;        //maxV = dd;    }    void setVV(int aa,int bb){        minV = min(aa,bb);        maxV = max(aa,bb);    }    bool equal(int aa,int bb){        if(yL==aa&&yR==bb){            return true;        }        return false;    }    };struct node2{    int xL,xR;    void set(int aa,int bb){        xL = aa;        xR = bb;    }    node1 subTR[MAXN0<<2];};node2 TR[MAXN0<<2];int mat[MAXN0][MAXN0];int maxF,minF;int max(int aa,int bb){    return aa>bb?aa:bb;}int min(int aa,int bb){    return aa<bb?aa:bb;}void buildsubTR(int ind1,int ind2,int L,int R){    TR[ind1].subTR[ind2].setLR(L, R);    // TR[ind1].subTR[ind2].maxV =0;    // TR[ind1].subTR[ind2].minV = INF;    if(L==R){        if(TR[ind1].xR==TR[ind1].xL){            TR[ind1].subTR[ind2].setVV(mat[TR[ind1].xR][R],mat[TR[ind1].xR][R]);        }        else {            TR[ind1].subTR[ind2].minV = min(TR[(ind1<<1)+1].subTR[(ind2)].minV,TR[ind1<<1].subTR[(ind2)].minV);            TR[ind1].subTR[ind2].maxV = max(TR[ind1<<1].subTR[(ind2)].maxV, TR[(ind1<<1)+1].subTR[(ind2)].maxV);        }        return;    }    int mid = (L+R)>>1;    buildsubTR(ind1,ind2<<1,L,mid);    buildsubTR(ind1, (ind2<<1)+1, mid+1,R);    TR[ind1].subTR[ind2].minV = min(TR[ind1].subTR[ind2<<1].minV, TR[ind1].subTR[(ind2<<1)+1].minV);    TR[ind1].subTR[ind2].maxV = max(TR[ind1].subTR[ind2<<1].maxV, TR[ind1].subTR[(ind2<<1)+1].maxV);}void buildTR(int ind,int L,int R,int L1,int R1){    TR[ind].set(L, R);    //buildsubTR(ind, 1, L1,R1);    if(L==R){        buildsubTR(ind, 1, L1,R1);        return;    }    int mid = (L+R)>>1;    buildTR(ind<<1,L,mid,L1,R1);    buildTR((ind<<1)+1,mid+1,R,L1,R1);    buildsubTR(ind, 1, L1,R1);    TR[ind].subTR[1].minV = min(TR[ind<<1].subTR[1].minV, TR[(ind<<1)+1].subTR[1].minV);    TR[ind].subTR[1].maxV = max(TR[ind<<1].subTR[1].maxV, TR[(ind<<1)+1].subTR[1].maxV);    }void Querysub(int ind1,int ind2,int L2,int R2){    if(TR[ind1].subTR[ind2].equal(L2,R2)){        minF = min(minF,TR[ind1].subTR[ind2].minV);        maxF = max(maxF,TR[ind1].subTR[ind2].maxV);        return;    }    //int mid;        if(TR[ind1].subTR[ind2].yL!=TR[ind1].subTR[ind2].yR){                int      mid = (TR[ind1].subTR[ind2].yL+TR[ind1].subTR[ind2].yR)>>1;        if(mid>=R2){            Querysub(ind1, ind2<<1, L2, R2);        }        else if(mid<L2){            Querysub(ind1, (ind2<<1)+1, L2, R2);        }        else {            Querysub(ind1, ind2<<1, L2, mid);            Querysub(ind1, (ind2<<1)+1, mid+1, R2);        }    }}void Query(int ind1,int L1,int R1,int L2,int R2){    if(TR[ind1].xL==L1&&TR[ind1].xR==R1){        Querysub(ind1,1,L2,R2);        return;    }        if(TR[ind1].xL!=TR[ind1].xR){        int mid = (TR[ind1].xL+TR[ind1].xR)>>1;        if(mid>=R1){            Query(ind1<<1, L1, R1, L2,R2);        }        else if(mid<L1){            Query((ind1<<1)+1,L1,R1,L2,R2);        }        else {            Query(ind1<<1, L1, mid, L2, R2);            Query((ind1<<1)+1, mid+1, R1, L2, R2);        }    }}void updatesub(int ind1,int ind2,int x,int y,int upd){    if(TR[ind1].subTR[ind2].equal(y,y)){        if(TR[ind1].xL==TR[ind1].xR){            TR[ind1].subTR[ind2].setVV(upd, upd);        }        else {            TR[ind1].subTR[ind2].minV = min(TR[(ind1<<1)+1].subTR[(ind2)].minV,TR[ind1<<1].subTR[(ind2)].minV);            TR[ind1].subTR[ind2].maxV = max(TR[ind1<<1].subTR[(ind2)].maxV, TR[(ind1<<1)+1].subTR[(ind2)].maxV);        }        return;    }    int mid = (TR[ind1].subTR[ind2].yL+TR[ind1].subTR[ind2].yR)>>1;    if(mid>=y){        updatesub(ind1, ind2<<1, x,y, upd);    }    else{        updatesub(ind1, (ind2<<1)+1, x, y, upd);    }    TR[ind1].subTR[ind2].minV = min(TR[ind1].subTR[ind2<<1].minV, TR[ind1].subTR[(ind2<<1)+1].minV);    TR[ind1].subTR[ind2].maxV = max(TR[ind1].subTR[ind2<<1].maxV, TR[ind1].subTR[(ind2<<1)+1].maxV);    }void update(int ind1,int x,int y,int upd){    if(TR[ind1].xL==x&&TR[ind1].xR==x){        updatesub(ind1, 1,x, y, upd);        return;    }        int mid = (TR[ind1].xL+TR[ind1].xR)>>1;    if(mid>=x){        update(ind1<<1, x, y, upd);    }    else {        update((ind1<<1)+1, x, y, upd);    }    updatesub(ind1, 1, x,y, upd);    TR[ind1].subTR[1].minV = min(TR[ind1<<1].subTR[1].minV, TR[(ind1<<1)+1].subTR[1].minV);    TR[ind1].subTR[1].maxV = max(TR[ind1<<1].subTR[1].maxV, TR[(ind1<<1)+1].subTR[1].maxV);}void prepro(int n){    //    for(int i=1;i<=n;++i){    //        for(int j=1;j<=n;++j){    //            if(j==1){    //                minmat[j][i] = maxmat[j][i] = mat[j][i];    //            }    //            else{    //                minmat[j][i] = min(minmat[j-1][i],);    //            }    //        }    //    }}int main(){    int T,n,Q,xi,yi,Li,L1,R1,L2,R2,tmp,ans;    int cas = 0;    scanf("%d",&T);    while(T--){        scanf("%d",&n);                for(int i=1;i<=n;++i){            for(int j=1;j<=n;++j){                scanf("%d",&mat[i][j]);                // update(1, i, j, mat[i][j]);            }        }        buildTR(1,1,n,1,n);                //prepro(n);        printf("Case #%d:\n",++cas);        scanf("%d",&Q);        while(Q--){            scanf("%d%d%d",&xi,&yi,&Li);            tmp = Li/2;            L1 = xi - tmp;            if(L1<=0)L1 = 1;            R1 = xi + tmp;            if(R1>n)R1 = n;            L2 = yi - tmp;            if(L2<=0)L2 = 1;            R2 = yi+tmp;            if(R2>n)R2 = n;            maxF = 0;            minF = INF;            Query(1,L1,R1,L2,R2);            ans = (maxF+minF)/2;            printf("%d\n",ans);            if(mat[xi][yi]!=ans){                update(1,xi,yi,ans);                mat[xi][yi] = ans;            }        }    }    return 0;}


0 0