• BZOJ 4066 简单题(KD树)


    【题目链接】 http://www.lydsy.com/JudgeOnline/problem.php?id=4066

    【题目大意】

      要求维护矩阵内格子加点和矩阵查询

    【题解】

      往KD树上加权值点,支持矩阵查询即可,每隔5000个插入暴力重构树。

    【代码】

    #include <cstdio>
    #include <algorithm>
    using namespace std;
    const int N=300000,INF=1e9;
    namespace KD_Tree{
        struct Dot{  
            int d[2],mn[2],mx[2],l,r,sz,sum,val;  
            Dot(){l=r=0;}  
            Dot(int x,int y,int c){d[0]=x;d[1]=y;val=c;l=r=sz=sum=0;}  
            int& operator [] (int x){return d[x];}  
        };  
        int D,dcnt=0,pt[N]; 
        Dot T[N];
        inline void umax(int&a,int b){if(a<b)a=b;}
        inline void umin(int&a,int b){if(a>b)a=b;}
        inline bool cmp(int x,int y){return T[x][D]<T[y][D];}
        inline void up(int x){
            T[x].sz=T[T[x].l].sz+T[T[x].r].sz+1;
            T[x].sum=T[T[x].l].sum+T[T[x].r].sum+T[x].val;
            T[x].mn[0]=T[x].mx[0]=T[x][0];  
            T[x].mn[1]=T[x].mx[1]=T[x][1]; 
            if(T[x].l){
                umax(T[x].mx[0],T[T[x].l].mx[0]);
                umin(T[x].mn[0],T[T[x].l].mn[0]);   
                umax(T[x].mx[1],T[T[x].l].mx[1]);
                umin(T[x].mn[1],T[T[x].l].mn[1]);
            }
            if(T[x].r){
                umax(T[x].mx[0],T[T[x].r].mx[0]);
                umin(T[x].mn[0],T[T[x].r].mn[0]);
                umax(T[x].mx[1],T[T[x].r].mx[1]);
                umin(T[x].mn[1],T[T[x].r].mn[1]);
            }
        }
        inline int NewDot(int x,int y,int c){
            ++dcnt; pt[dcnt]=dcnt;
            T[dcnt][0]=x; T[dcnt][1]=y; T[dcnt].val=c;
            return up(dcnt),dcnt;
        }
        // 查询矩阵内数字和
        int query(int x,int x0,int y0,int x1,int y1){
            if(!x||T[x].mn[0]>x1||T[x].mx[0]<x0||T[x].mn[1]>y1||T[x].mx[1]<y0)return 0;  
            if(T[x].mn[0]>=x0&&T[x].mx[0]<=x1&&T[x].mn[1]>=y0&&T[x].mx[1]<=y1)return T[x].sum;  
            int res=0;  
            if(T[x][0]>=x0&&T[x][0]<=x1&&T[x][1]>=y0&&T[x][1]<=y1)res+=T[x].val;  
            return res+query(T[x].l,x0,y0,x1,y1)+query(T[x].r,x0,y0,x1,y1); 
        }
        void Insert(int&x,int D,const Dot&p){  
            if(!x){x=NewDot(p.d[0],p.d[1],p.val);return;}  
            if(p.d[D]<T[x][D])Insert(T[x].l,D^1,p);  
            else Insert(T[x].r,D^1,p);  
            up(x);  
        }
        // 暴力重构
        int Rebuild(int l,int r,int now){  
            if(l>r)return 0;  
            int mid=(l+r)>>1,x;  
            D=now;  
            nth_element(pt+l,pt+mid,pt+r+1,cmp);  
            x=pt[mid];  
            T[x].l=Rebuild(l,mid-1,now^1);  
            T[x].r=Rebuild(mid+1,r,now^1);  
            return up(x),x;  
        } 
    }
    int n,op,x0,y0,x1,y1,c,ans=0,root=0;
    int main(){
        scanf("%d",&n);
        while(scanf("%d",&op)){
            if(op==3)break;
            if(op==1){
                scanf("%d%d%d",&x0,&y0,&c);
                x0^=ans,y0^=ans,c^=ans;
                KD_Tree::Insert(root,0,KD_Tree::Dot(x0,y0,c));
                if(KD_Tree::dcnt%5000==0)root=KD_Tree::Rebuild(1,KD_Tree::dcnt,0);
            }else{
                scanf("%d%d%d%d",&x0,&y0,&x1,&y1);
                x0^=ans,y0^=ans,x1^=ans,y1^=ans;
                printf("%d
    ",ans=KD_Tree::query(root,x0,y0,x1,y1));
            }
        }return 0;
    }
  • 相关阅读:
    调用EasyPlayer播放器报错FlvPlayer.load() has been called,pleasse call unload() first!,如何处理?
    开发webrtc P2P连接报错DOMException: Failed to execute XXXXXX排查及优化
    异地视频共享/组网工具EasyNTS如何进行穿透接口的数据迁移?
    视频监控如何实现异地共享/组网?EasyNTS解决远程难题
    每日总结
    关于RHEL7.5无法使用yum命令的解决方法
    java后端学习-第一部分java基础:面向对象编程
    每日总结
    每日总结
    每日总结
  • 原文地址:https://www.cnblogs.com/forever97/p/bzoj4066.html
Copyright © 2020-2023  润新知