【题目分析】

直接x,y二维轮番划分,暴力即可。

套上替罪羊,打碎重构,对于时间复杂度有了保证。

写起来好麻烦,重构的技巧很棒!

【代码】

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>

using namespace std;

#define maxn 200005
#define inf 0x3f3f3f3f
#define lim 0.7
#define L t[o].c[0]
#define R t[o].c[1]
#define mid (l+r>>1)
#define F(i,j,k) for (int i=j;i<=k;++i)

struct node{
    int d[2],c[2];
    int mx[2],mn[2],sum,v,siz,D;
    int& operator [] (int x){return d[x];}
}t[maxn],now;
int p[maxn];
int opt=0,D,rt=0,ans=0,tot=0,cnt;
inline bool cmp(int x,int y){return t[x][D]<t[y][D];}
void pushup(int k)
{
    for (int i=0;i<2;++i)
    {
        t[k].mn[i]=min(t[t[k].c[0]].mn[i],min(t[t[k].c[1]].mn[i],t[k].mn[i]));
        t[k].mx[i]=max(t[t[k].c[0]].mx[i],max(t[t[k].c[1]].mx[i],t[k].mx[i]));
    }
    t[k].sum=t[t[k].c[0]].sum+t[t[k].c[1]].sum+t[k].v;
    t[k].siz=t[t[k].c[0]].siz+t[t[k].c[1]].siz+1;
}
inline int build(int l,int r,int dir){
    D=dir;
    nth_element(p+l,p+mid,p+r+1,cmp);
    int o=p[mid];
    t[o].D=dir;
    F(i,0,1) t[o].mn[i]=t[o].mx[i]=t[o][i];
    t[o].sum=t[o].v;
    L=l<mid ? build(l,mid-1,dir^1) : 0;
    R=mid<r ? build(mid+1,r,dir^1) : 0;
    pushup(o);
    return o;
}
inline void dfs(int o){
    if (!o) return;
    dfs(L);
    p[++cnt]=o;
    dfs(R);
}
inline void rebuild(int &o){
    cnt=0;
    dfs(o);
    o=build(1,cnt,t[o].D);
}

void ins(int &o,int dir)
{
    if (!o)
    {
        o=++tot;
        t[o]=now;
        for (int i=0;i<2;++i) t[o].mn[i]=t[o].mx[i]=t[o].d[i];
        t[o].siz=1;
        t[o].D=dir;
        t[o].sum=t[o].v;
        return ;
    }
    if (now.d[dir]<t[o].d[dir])
    {
        ins(t[o].c[0],dir^1);
        pushup(o);
        if ((double)t[t[o].c[0]].siz>(double)t[o].siz*lim) rebuild(o);
    }
    else
    {
        ins(t[o].c[1],dir^1);
        pushup(o);
        if ((double)t[t[o].c[1]].siz>(double)t[o].siz*lim) rebuild(o);
    }
}

void print(int o){
    if (!o) return;
    printf("%d t[o].mn[0]=%d t[o].mn[1]=%d t[o].mx[0]=%d t[o].mx[1]=%d\n",o,t[o].mn[0],t[o].mn[1],t[o].mx[0],t[o].mx[1]);
    print(L);
    print(R);
}

int query(int o,int x1,int y1,int x2,int y2)
{
    if (!o) return 0;
    if (t[o].mn[0]>=x1 && t[o].mn[1]>=y1 && t[o].mx[0]<=x2 && t[o].mx[1]<=y2)
        return t[o].sum;
    else
    {
        int ret=0;
        if (t[o].d[0]>=x1&&t[o].d[0]<=x2&&t[o].d[1]>=y1&&t[o].d[1]<=y2)
            ret+=t[o].v;
        if (t[t[o].c[0]].mn[0]>x2||t[t[o].c[0]].mx[0]<x1||t[t[o].c[0]].mn[1]>y2||t[t[o].c[0]].mx[1]<y1);
            else ret+=query(t[o].c[0],x1,y1,x2,y2);
        if (t[t[o].c[1]].mn[0]>x2||t[t[o].c[1]].mx[0]<x1||t[t[o].c[1]].mn[1]>y2||t[t[o].c[1]].mx[1]<y1);
            else ret+=query(t[o].c[1],x1,y1,x2,y2);
        return ret;
    }
}

int main()
{
    for (int i=0;i<2;++i) t[rt].mx[i]=-inf,t[rt].mn[i]=inf;
    t[rt].siz=t[rt].sum=t[rt].v=0;
    scanf("%*d");
    while (scanf("%d",&opt)!=EOF&&opt!=3)
    {
        if (opt==1)
        {
            scanf("%d%d%d",&now.d[0],&now.d[1],&now.v);
            now.d[0]^=ans; now.d[1]^=ans; now.v^=ans;
            ins(rt,1);
        }
        else{
            int x1,y1,x2,y2;
            scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
            x1^=ans;y1^=ans;x2^=ans;y2^=ans;
            printf("%d\n",ans=query(rt,x1,y1,x2,y2));
        }
    }
}

  

BZOJ 4066 简单题 ——KD-Tree套替罪羊树的更多相关文章

  1. bzoj 4066: 简单题 K-D树

    题目大意: http://www.lydsy.com/JudgeOnline/problem.php?id=4066 题解 我们把每次的修改操作都当作二维平面上多了一个权值点 对于每组询问可以看做求一 ...

  2. bzoj 4066: 简单题 kd-tree

    4066: 简单题 Time Limit: 50 Sec  Memory Limit: 20 MBSubmit: 234  Solved: 82[Submit][Status][Discuss] De ...

  3. bzoj 4066 简单题——KDtree(带重构)

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4066 带部分重构的KDtree.就是那个替罪羊树思想的. 写了对拍,调了半天,发现忘了 re ...

  4. BZOJ4066:简单题(K-D Tree)

    Description 你有一个N*N的棋盘,每个格子内有一个整数,初始时的时候全部为0,现在需要维护两种操作:   命令 参数限制 内容 1 x y A 1<=x,y<=N,A是正整数 ...

  5. P4148 简单题 k-d tree

    思路:\(k-d\ tree\) 提交:2次 错因:整棵树重构时的严重错误:没有维护父子关系(之前写的是假重构所以没有维护父子关系) 题解: 遇到一个新的点就插进去,如果之前出现过就把权值加上. 代码 ...

  6. BZOJ 4066 简单题(KD树)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=4066 [题目大意] 要求维护矩阵内格子加点和矩阵查询 [题解] 往KD树上加权值点,支 ...

  7. bzoj 4066 & bzoj 2683 简单题 —— K-D树(含重构)

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

  8. bzoj 4066: 简单题

    #include<cstdio> #include<iostream> #include<cstdlib> #include<algorithm> #d ...

  9. 【CJOJ2433】陌上花开 树状数组套替罪羊树

    [CJOJ2433]陌上花开 树状数组套替罪羊树 蛤?bzoj?没权限QAQ 蛤?CDQ?看了好久没看懂QwQ 好吧我会拿cdq再写一遍的 为啥我感觉这东西比cdq好写 只好拿树状数组套替罪羊树水水了 ...

随机推荐

  1. Apache服务器安装过程及问题的解决(for windows system32bit)

    在使用Hbuilder设计网站时,在制作本站搜索时,用到了Php文件,而Hbuilder的内置web服务器不支持php的解析, 所以需要安装配置外部服务器,有多个选择,我安装的apache服务器,并遇 ...

  2. 阿里提前批校招内推offer经历

    经过一个半月的阿里内推面试,今天终于收到了阿里的offer邮件 .阿里的内推面试一共有四轮,本人是7月19号投的内推邮件,8月28号收到了offer的邮件.首先本人谈谈内推的看法.内推是公司招聘人才的 ...

  3. SqlDataReader和SqlDataAdapter

    SqlDataReader 高效,功能弱,只读访问SqlDataAdapter 强大,要求资源也大一点 SqlDataReader 只能在保持跟数据库连接的状态下才可以读取... SqlDataAda ...

  4. Javascript设计模式学习三(策略模式)

    定义:定义一系列的算法,把它们一个个封装起来,并且使它们可以互相替换.目的:将算法的使用和算法的实现分离开来.比如: if(input == 'A'){ return 1; } if(input == ...

  5. WebClient 实现多文件/文本同时上传

    public class CreateBytes { Encoding encoding = Encoding.UTF8; /**/ /// <summary> /// 拼接所有的二进制数 ...

  6. 汤姆大叔 javascript 系列 第20课 最后的5到javascript题目

    博客链接:http://www.cnblogs.com/TomXu/archive/2012/02/10/2342098.html 原题: 大叔注:这些题目也是来自出这5个题目的人,当然如果你能答对4 ...

  7. 【Android自学日记】【转】Android Fragment 真正的完全解析(上)

    自从Fragment出现,曾经有段时间,感觉大家谈什么都能跟Fragment谈上关系,做什么都要问下Fragment能实现不~~~哈哈,是不是有点过~~~ 本篇博客力求为大家说明Fragment如何产 ...

  8. 怎样在Windows资源管理器中添加右键菜单以及修改右键菜单顺序

    有时,我们需要在Windows资源管理器的右键菜单中添加一些项,以方便使用某些功能或程序. 比如我的电脑上有一个免安装版的Notepad++,我想在所有文件的右键菜单中添加一项用Notepad++打开 ...

  9. 【备忘】Conky配置

    贴配置: background yes use_xft yes xftfont Sans:size= xftalpha 0.8 update_interval own_window yes own_w ...

  10. Debian8升级4.5内核

    本文讲述如何升级Debian8的内核到4.5版本 0x01:去linux kernel官网https://www.kernel.org/下载4.5的内核,选择tar.xz格式 0x02:想办法把下载好 ...