zoukankan      html  css  js  c++  java
  • 洛谷4148 & BZOJ4066:简单题——题解

    https://www.lydsy.com/JudgeOnline/problem.php?id=4066

    https://www.luogu.com.cn/problem/P4148

    你有一个N*N的棋盘,每个格子内有一个整数,初始时的时候全部为0,现在需要维护两种操作:

     

    命令

    参数限制

    内容

    1 x y A

    1<=x,y<=N,A是正整数

    将格子x,y里的数字加上A

    2 x1 y1 x2 y2

    1<=x1<= x2<=N

    1<=y1<= y2<=N

    输出x1 y1 x2 y2这个矩形内的数字和

    3

    终止程序

    K-D树板子题,好的我重写了一个多小时的板子

    1操作就正常加点,2操作类似线段树一样查询,如果当前区间所有点都在这里面那就全加上,否则看是否区域有重叠,如果没有那么肯定没有贡献直接结束,否则往下遍历。

    然后插入的时候请像替罪羊树那样拍扁重建,注意重建的点数据清空(比如它的左右儿子),我就是因为这个debug了1h+……

    #include<cmath>
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    typedef double dl;
    typedef long long ll;
    const int K=2;
    const int N=2e5+5;
    const dl alpha=0.7;
    inline int read(){
        int X=0,w=0;char ch=0;
        while(!isdigit(ch)){w|=ch=='-';ch=getchar();}
        while(isdigit(ch))X=(X<<3)+(X<<1)+(ch^48),ch=getchar();
        return w?-X:X;
    }
    int D,n,tot,num,root,rubbish[N];
    struct Point{
        int d[K],w;
        bool operator <(const Point &a)const{
            return d[D]<a.d[D];
        }
    }a[N];
    struct KDTREE{
        int s[2],x[2],y[2];
        int sz,sum;
        Point p;
    }tr[N];
    #define ls tr[o].s[0]
    #define rs tr[o].s[1]
    #define cmax(a,b) (a<b?a=b:a)
    #define cmin(a,b) (a>b?a=b:a)
    inline int newnode(){
        if(!tot)return ++n;
        return rubbish[tot--];
    }
    inline void upd(int f,int x){
        cmin(tr[f].x[0],tr[x].x[0]),cmax(tr[f].x[1],tr[x].x[1]);
        cmin(tr[f].y[0],tr[x].y[0]),cmax(tr[f].y[1],tr[x].y[1]);
    }
    inline void pushup(int o){
        tr[o].x[0]=tr[o].x[1]=tr[o].p.d[0];
        tr[o].y[0]=tr[o].y[1]=tr[o].p.d[1];
        tr[o].sz=tr[ls].sz+tr[rs].sz+1;
        tr[o].sum=tr[ls].sum+tr[rs].sum+tr[o].p.w;
        if(ls)upd(o,ls);if(rs)upd(o,rs);
    }
    int build(int l,int r,int d){
        D=d;int mid=(l+r)>>1;
        nth_element(a+l,a+mid,a+r+1);
        int o=newnode();
        tr[o].p=a[mid];
        if(l<mid)ls=build(l,mid-1,d^1),upd(o,ls);else ls=0;
        if(mid<r)rs=build(mid+1,r,d^1),upd(o,rs);else rs=0;
        pushup(o);return o;
    }
    void slap(int o){
        if(ls)slap(ls);
        a[++num]=tr[o].p;rubbish[++tot]=o;
        if(rs)slap(rs);
    }
    inline void check(int &o,int d){
        if(alpha*tr[o].sz<tr[ls].sz||alpha*tr[o].sz<tr[rs].sz)
            num=0,slap(o),o=build(1,num,d);
    }
    void insert(int &o,Point x,int d){
        if(!o){
            o=newnode();tr[o].p=x;pushup(o);
            return;
        }
        if(x.d[d]<=tr[o].p.d[d])insert(ls,x,d^1);
        else insert(rs,x,d^1);
        pushup(o);check(o,d);
    }
    inline bool inside(int o,Point x,Point y){
        return x.d[0]<=tr[o].x[0]&&tr[o].x[1]<=y.d[0]
                &&x.d[1]<=tr[o].y[0]&&tr[o].y[1]<=y.d[1];
    }
    inline bool outside(int o,Point x,Point y){
        return x.d[0]>tr[o].x[1]||tr[o].x[0]>y.d[0]
                ||x.d[1]>tr[o].y[1]||tr[o].y[0]>y.d[1];
    }
    int query(int o,Point x,Point y){
        if(!o)return 0;
        if(inside(o,x,y))return tr[o].sum;
        if(outside(o,x,y))return 0;
        int ans=0;
        if(x.d[0]<=tr[o].p.d[0]&&tr[o].p.d[0]<=y.d[0]
                &&x.d[1]<=tr[o].p.d[1]&&tr[o].p.d[1]<=y.d[1])
                    ans=tr[o].p.w;
        return ans+query(ls,x,y)+query(rs,x,y);
    }
    int main(){
        int m=read(),lans=0;
        while(1){
            int op=read();
            if(op==1){
                int x=read()^lans,y=read()^lans,A=read()^lans;
                insert(root,(Point){x,y,A},0);
            }
            if(op==2){
                int x1=read()^lans,y1=read()^lans;
                int x2=read()^lans,y2=read()^lans;
                printf("%d
    ",lans=query(root,(Point){x1,y1,0},(Point){x2,y2,0}));
            }
            if(op==3)return 0;
        }
    }

    +++++++++++++++++++++++++++++++++++++++++++

     +本文作者:luyouqi233。               +

     +欢迎访问我的博客:http://www.cnblogs.com/luyouqi233/+

    +++++++++++++++++++++++++++++++++++++++++++

  • 相关阅读:
    CCOrbitCamera卡牌翻转效果
    用CCRenderTexture和BlendFunc制作游戏教学时使用的黑色覆盖层
    cocos2d-x触摸分发器原理
    cocos2d-x动作原理
    c++之函数原型
    cocos2d-x调度器原理
    cocos2d-x之MoonWarriors用c++实现
    cocos2d-x回收池原理
    SQL*Net more data to client等待事件
    asynch descriptor resize等待事件
  • 原文地址:https://www.cnblogs.com/luyouqi233/p/12287389.html
Copyright © 2011-2022 走看看