思路:\(k-d\ tree\)

提交:2次

错因:整棵树重构时的严重错误:没有维护父子关系(之前写的是假重构所以没有维护父子关系)

题解:

遇到一个新的点就插进去,如果之前出现过就把权值加上。

代码

#include<cstdio>
#include<iostream>
#include<algorithm>
#define ull unsigned long long
#define ll long long
#define R register int
using namespace std;
#define pause (for(R i=1;i<=10000000000;++i))
#define In freopen("NOIPAK++.in","r",stdin)
#define Out freopen("out.out","w",stdout)
namespace Fread {
static char B[1<<15],*S=B,*D=B;
#ifndef JACK
#define getchar() (S==D&&(D=(S=B)+fread(B,1,1<<15,stdin),S==D)?EOF:*S++)
#endif
inline int g() {
R ret=0,fix=1; register char ch; while(!isdigit(ch=getchar())) fix=ch=='-'?-1:fix;
if(ch==EOF) return EOF; do ret=ret*10+(ch^48); while(isdigit(ch=getchar())); return ret*fix;
} inline bool isempty(const char& ch) {return (ch<=36||ch>=127);}
inline void gs(char* s) {
register char ch; while(isempty(ch=getchar()));
do *s++=ch; while(!isempty(ch=getchar()));
}
} using Fread::g; using Fread::gs;
namespace Luitaryi {
const int N=200010; const double A=0.707;
int n,top,tot,cnt,D,T,ans,rt;
struct P{int d[2],w;
inline bool operator <(const P& that) const {return d[D]<that.d[D];}
}p[N];
struct node {
int mx[2],mn[2],fa,sz,dim,sum,lson,rson; P p;
#define ls (t[tr].lson)
#define rs (t[tr].rson)
#define fa(tr) (t[tr].fa)
#define dim(tr) (t[tr].dim)
#define mx(tr,i) (t[tr].mx[i])
#define mn(tr,i) (t[tr].mn[i])
#define P(tr,i) (t[tr].p.d[i])
#define sum(tr) (t[tr].sum)
#define sz(tr) (t[tr].sz)
#define vl(tr) (t[tr].p.w)
}t[N];
int buff[N];
inline void upd(int tr,int dim) {
for(R i=0;i<=1;++i) {
mn(tr,i)=mx(tr,i)=P(tr,i);
if(ls) mx(tr,i)=max(mx(tr,i),mx(ls,i)),mn(tr,i)=min(mn(tr,i),mn(ls,i)),fa(ls)=tr;
if(rs) mx(tr,i)=max(mx(tr,i),mx(rs,i)),mn(tr,i)=min(mn(tr,i),mn(rs,i)),fa(rs)=tr;
} sz(tr)=sz(ls)+sz(rs)+1; sum(tr)=sum(ls)+sum(rs)+vl(tr); dim(tr)=dim;
}
inline void flat(int tr) {
if(ls) flat(ls);
p[++cnt]=t[tr].p,buff[++top]=tr;
if(rs) flat(rs);
}
inline int cre() {return top?buff[top--]:++tot;}
inline int build(int l,int r,int dim) {
if(l>r) return 0; R tr=cre(),md=l+r>>1;
D=dim,nth_element(p+l,p+md,p+r+1);
t[tr].p=p[md]; ls=build(l,md-1,dim^1),rs=build(md+1,r,dim^1);
upd(tr,dim); return tr;
}
inline void ins(int& tr,int fa,int dim,const P& tmp) {
if(!tr) {tr=cre(),t[tr].p=tmp,ls=rs=0,upd(tr,dim); return ;}
if(P(tr,0)==tmp.d[0]&&P(tr,1)==tmp.d[1]) vl(tr)+=tmp.w;
else P(tr,dim)>tmp.d[dim]?ins(ls,tr,dim^1,tmp):ins(rs,tr,dim^1,tmp);
upd(tr,dim); if(sz(tr)*A<max(sz(ls),sz(rs))) T=tr;
}
inline bool in(const node& ran,const node& dst) {
return ran.mn[0]>=dst.mn[0]&&ran.mx[0]<=dst.mx[0]
&&ran.mn[1]>=dst.mn[1]&&ran.mx[1]<=dst.mx[1];
}
inline bool out(const node& ran,const node& dst) {
return ran.mn[0]>dst.mx[0]||ran.mn[1]>dst.mx[1]
||ran.mx[0]<dst.mn[0]||ran.mx[1]<dst.mn[1];
}
inline int query(int tr,const node& dst) {
if(!tr||out(t[tr],dst)) return 0;
if(in(t[tr],dst)) return t[tr].sum;
R ret=1; for(R i=0;i<=1;++i) ret=ret&&(P(tr,i)<=dst.mx[i]&&P(tr,i)>=dst.mn[i]);
return ret*vl(tr)+query(ls,dst)+query(rs,dst);
}
inline void main() {
n=g(); while(1) { R op=g();
if(op==1) { register P tmp;
tmp.d[0]=g()^ans,tmp.d[1]=g()^ans,tmp.w=g()^ans;
ins(rt,rt,0,tmp); if(T) { flat(T);
if(T==rt) rt=build(1,cnt,0);
else t[fa(T)].rson==T?t[fa(T)].rson=build(1,cnt,dim(T)):t[fa(T)].lson=build(1,cnt,dim(T));
T=cnt=0;
}
} if(op==2) { register node tmp;
tmp.mn[0]=g()^ans,tmp.mn[1]=g()^ans,tmp.mx[0]=g()^ans,tmp.mx[1]=g()^ans;
printf("%d\n",ans=query(rt,tmp));
} if(op==3) break;
}
}
}
signed main() {
Luitaryi::main(); return 0;
}

2019.07.25

P4148 简单题 k-d tree的更多相关文章

  1. Luogu P4148 简单题(K-D Tree)

    题面 题解 因为强制在线,所以我们不能$cdq$分治,所以考虑用$KDT$,$KDT$维护一个矩阵,然后询问的时候如果当前矩形在询问区间内,直接记贡献,否则判断当前点是否在矩阵内,然后左右分别递归下去 ...

  2. 洛谷 P4148 简单题 解题报告

    P4148 简单题 题意 维护单点加与矩形求和,强制在线 说明 \(n\le 500000,m\le 200000\),\(4000ms / 20MB\) kd-tree 复杂度我不懂 是一颗平衡树, ...

  3. 洛谷 P4148 简单题 KD-Tree 模板题

    Code: //洛谷 P4148 简单题 KD-Tree 模板题 #include <cstdio> #include <algorithm> #include <cst ...

  4. 简单题(K-D Tree)

    简单题不简单-- 我们把单点加操作改成插入一个权值为增加量的点,将问题转化成询问一个矩阵中所有点的和,用 \(K-D\ Tree\) 维护,时间复杂度 \(O(n\sqrt{n})\) \(Code\ ...

  5. luogu P4148 简单题

    传送门 这题真简单,直接把\(CDQ\)给ban掉了 其实数据范围比较小可以直接二维树状数组,我们看数据范围,发现点的个数比N还小,可以考虑用一些奇怪的数据结构 说的就是你,\(KD tree\) \ ...

  6. P4148 简单题(KDTree)

    传送门 KDTree 修改权值当做插入节点,不平衡就暴力重构,询问的时候判断当前节点代表的矩形是否在询问的矩形的,是的话返回答案,相离返回0,否则的话判断当前点是否在矩形内,然后继续递归下去 //mi ...

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

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

  8. acm.njupt 1001-1026 简单题

    点击可展开上面目录 Acm.njupt 1001-1026简单题 第一页许多是简单题,每题拿出来说说,没有必要,也说不了什么. 直接贴上AC的代码.初学者一题题做,看看别人的AC代码,寻找自己的问题. ...

  9. BZOJ 2683: 简单题

    2683: 简单题 Time Limit: 50 Sec  Memory Limit: 128 MBSubmit: 913  Solved: 379[Submit][Status][Discuss] ...

随机推荐

  1. 解决maven项目无法读取src/main/java目录下面的配置文件问题

    我们在用Mybatis去操作底层数据库的时候,需要用到xml配置文件,一般我们是把配置文件和dao放置在同一层目录. 但是在用idea操作maven项目的时候,我们可能会遇到无法读取到dao对应的ma ...

  2. VC++实现遍历指定文件夹

    VC++实现遍历指定文件夹,并进行深度遍历,一级,二级...最终列出该文件夹下所有文件全路径. #include "stdafx.h" #include <iostream& ...

  3. Python复习笔记02

    语句表达式: 在Python中支持遍历循环的对象:可迭代器对象,支持迭代协议的对象 比如列表list没有迭代功能只是可迭代对象 迭代:迭代协议 --> 例:f.__next__() 属于f的迭代 ...

  4. Scratch运动模块——有趣的弹球游戏(一)

    大家好!我是蓝老师,有了前几期Scratch的基础,相信大家早已摩拳擦掌,跃跃欲试了,甚至还有些小伙伴已经编写了非常不错的程序. 学习编程就是这样不断探索.主动思考.解决问题的过程. 本期内容: 课程 ...

  5. 使用QSaveFile类安全的读写文件(继承自QFileDevice,与QFile并列)

    QSaveFile类也是一种I/O设备,来用来读写文本文件和二进制文件,但使用该类的话,在写入操作失败时不会导致已经存在的数据丢失. 该类在执行写操作时,会先将内容写入到一个临时文件中,如果没有错误发 ...

  6. KNN算法识别手写数字

    需求: 利用一个手写数字“先验数据”集,使用knn算法来实现对手写数字的自动识别: 先验数据(训练数据)集: ♦数据维度比较大,样本数比较多. ♦ 数据集包括数字0-9的手写体. ♦每个数字大约有20 ...

  7. Seaborn(一)之风格管理

    Seaborn简介 seaborn同matplotlib一样,也是Python进行数据可视化分析的重要第三方包.但seaborn是在 matplotlib的基础上进行了更高级的API封装,使得作图更加 ...

  8. ndk-build 修改输出so位置 (change ndk-build output so lib file path )

    期望的目录结构: Folder --- | --- build.bat | --- Source | --- All sources codes *.cpp *.h | --- Android --- ...

  9. 移动端自适应之flexible

    移动端自适应之flexible 作用:flexible的作用是使页面可以适配不同移动终端 原理:在页面html标签上添加style = "font-size: 36px;"样式,设 ...

  10. MysqL之数值函数

    1.CEIL() 用法:向上取整 举例: mysql> select CEIL(3.5); +-----------+ | CEIL(3.5) | +-----------+ | +------ ...