• [UVA-11297]Census——二维线段树


    Census

            求矩形区域最大最小值,单点修改。

            建立x方向的线段树,x方向线段树的每个节点都是一个y方向的线段树。查询复杂度log(n)*log(m),单点修改复杂度log(n)*log(m)。修改时对于x的叶节点和非叶节点需要区别对待。

    #include<bits/stdc++.h>
    using namespace std;
    
    const int N=510;
    struct SegmentTree2D{
        int Max[N*4][N*4],Min[N*4][N*4],n,m;//n:x范围,m:y轴范围
        int ox,y1,y2,Mi,Ma,x,y,v;//一些用于询问修改的变量,避免传参太多
        bool xleaf;//x方向是否为叶子
        void updatey(int o,int ly,int ry){
            if(ly==ry){
                if(xleaf){Max[ox][o]=Min[ox][o]=v;return;}
                Max[ox][o]=max(Max[2*ox][o],Max[2*ox+1][o]);
                Min[ox][o]=min(Min[2*ox][o],Min[2*ox+1][o]);
                return;
            }
            int mid=(ly+ry)>>1,lc=2*o,rc=2*o+1;
            if(y<=mid)updatey(lc,ly,mid);
            else updatey(rc,mid+1,ry);
            Max[ox][o]=max(Max[ox][lc],Max[ox][rc]);
            Min[ox][o]=min(Min[ox][lc],Min[ox][rc]);
        }
        void updatex(int o,int lx,int rx){
            if(lx==rx){ox=o;xleaf=true;updatey(1,1,m);return;}
            int mid=(lx+rx)>>1,lc=2*o,rc=2*o+1;
            if(x<=mid)updatex(lc,lx,mid);
            else updatex(rc,mid+1,rx);
            ox=o;xleaf=false;
            updatey(1,1,m);//非叶节点更新
        }
        void update(int posx,int posy,int val){
            x=posx;y=posy;v=val;updatex(1,1,n);
        }
        void queryy(int o,int y1,int y2,int ly,int ry){
            if(y1<=ly&&y2>=ry){
                Mi=min(Mi,Min[ox][o]);
                Ma=max(Ma,Max[ox][o]);
                return;
            }
            int mid=(ly+ry)>>1,lc=2*o,rc=2*o+1;
            if(y1<=mid)queryy(lc,y1,y2,ly,mid);
            if(y2>mid)queryy(rc,y1,y2,mid+1,ry);
        }
        void queryx(int o,int x1,int x2,int lx,int rx){
            if(x1<=lx&&x2>=rx){ox=o;queryy(1,y1,y2,1,m);return;}
            int mid=(lx+rx)>>1,lc=2*o,rc=2*o+1;
            if(x1<=mid)queryx(lc,x1,x2,lx,mid);
            if(x2>mid)queryx(rc,x1,x2,mid+1,rx);
        }
        void query(int xa,int xb,int ya,int yb){
            Mi=1e9;Ma=-1e9;
            y1=ya;y2=yb;
            queryx(1,xa,xb,1,n);
        }
        void buildy(int o,int ly,int ry){
            if(ly==ry){
                if(xleaf){
                    int v;scanf("%d",&v);
                    Max[ox][o]=Min[ox][o]=v;
                    return;
                }
                Max[ox][o]=max(Max[2*ox][o],Max[2*ox+1][o]);
                Min[ox][o]=min(Min[2*ox][o],Min[2*ox+1][o]);
                return;
            }
            int mid=(ly+ry)>>1,lc=2*o,rc=2*o+1;
            buildy(lc,ly,mid);buildy(rc,mid+1,ry);
            Max[ox][o]=max(Max[ox][lc],Max[ox][rc]);
            Min[ox][o]=min(Min[ox][lc],Min[ox][rc]);
        }
        void buildx(int o,int lx,int rx){
            if(lx==rx){ox=o;xleaf=true;
            buildy(1,1,m);return;}
            int mid=(lx+rx)>>1,lc=2*o,rc=2*o+1;
            buildx(lc,lx,mid);buildx(rc,mid+1,rx);
            ox=o;xleaf=false;
            buildy(1,1,m);
        }
    };
    SegmentTree2D T;
    int main(){
        int n,v;
        scanf("%d",&n);
        T.n=T.m=n;T.buildx(1,1,n);
        int q;char op;
        scanf("%d",&q);
        while(q--){
            int x1,x2,y1,y2;
            scanf(" %c",&op);
            if(op=='q'){
                scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
                T.query(x1,x2,y1,y2);
                printf("%d %d
    ",T.Ma,T.Mi);
            }else{
                scanf("%d%d%d",&x1,&y1,&x2);
                T.update(x1,y1,x2);
            }
        }
        return 0;
    }
    View Code
  • 相关阅读:
    深度学习面试问题
    重新学习pytorch的库函数等..
    新电脑的操作系统win10的所有设置问题汇总
    二叉搜索树,和红黑树,
    Most common words
    Word histogram
    Random numbers
    Word frequency analysis
    DSU
    Sequences of sequences
  • 原文地址:https://www.cnblogs.com/zpengst/p/12559134.html
Copyright © 2020-2023  润新知