第一次遇见强制在线的题目 每个操作都和前面的ans有关 所以不能直接离线做

在这个问题中 kdtree更像一个线段树在一维单点修改区间询问的拓展一样

如果区间被询问区间完全包含 就不用继续递归

插入时如果该点已被修改 就不用建新点

由于kdtree是一个二叉搜索树 所以如果数据构造 是可以卡出一条链的 所以需要在插入一定点数之后开始重构这个kdtree 使深度维持在一个可控范围内

因为写错了in_it函数找了一天bug

#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<map>
#include<math.h>
#include<queue>
#include<string>
using namespace std;
#define L long long
const int INF = 999999999 ;
const int maxn = 200050 ;
int n , root , cmp_d , m;
struct node {
int d[2] , Max[2] , Min[2] ;
int l , r ;
int sum ;
int z ;
}a[maxn];
int x, y , X;
int x1, x2, y11 ,y2 ;
bool cmp(node a , node b ){return ((a.d[cmp_d] < b.d[cmp_d]) || (a.d[cmp_d] == b.d[cmp_d] && a.d[!cmp_d] < b.d[!cmp_d])) ;}
void up(int p , int k) {
a[p].Max[0] = max(a[p].Max[0] , a[k].Max[0]) ;
a[p].Max[1] = max(a[p].Max[1] , a[k].Max[1]) ;
a[p].Min[0] = min(a[p].Min[0] , a[k].Min[0]) ;
a[p].Min[1] = min(a[p].Min[1] , a[k].Min[1]) ;
a[p].sum += a[k].sum ;
}
int build(int l , int r , int D){
int mid = (l+r) / 2 ;
cmp_d = D;
nth_element(a+1+l,a+1+mid,a+1+r,cmp) ;
a[mid].Max[0] = a[mid].Min[0] = a[mid].d[0] ;
a[mid].Max[1] = a[mid].Min[1] = a[mid].d[1] ;
a[mid].sum = a[mid].z ;
if(l != mid) a[mid].l = build(l,mid-1,D^1) ; else a[mid].l = 0;
if(r != mid) a[mid].r = build(mid+1,r,D^1) ; else a[mid].r = 0;
if(a[mid].l)up(mid,a[mid].l) ;
if(a[mid].r)up(mid,a[mid].r) ;
return mid ;
}
void inse(int x , int y , int X) {
int p = root ;
int D = 0 ;
while(true) {
if(x > a[p].Max[0]) a[p].Max[0] = x ;
if(x < a[p].Min[0]) a[p].Min[0] = x ;
if(y > a[p].Max[1]) a[p].Max[1] = y ;
if(y < a[p].Min[1]) a[p].Min[1] = y ;
a[p].sum += X ;
if(x == a[p].d[0] && y == a[p].d[1]) {
a[p].z += X ;
return ;
}
else {
if(D == 0) {
if(x <= a[p].d[0]) {
if(a[p].l) p = a[p].l ;
else {
n ++ ;
a[n].l = a[n].r = 0 ;
a[n].Max[0] = a[n].Min[0] = a[n].d[0] = x ;
a[n].Min[1] = a[n].Max[1] = a[n].d[1] = y ;
a[n].sum = a[n].z = X ;
a[p].l = n ;
return ;
}
}
else {
if(a[p].r) p = a[p].r ;
else {
n ++ ;
a[n].l = a[n].r = 0 ;
a[n].Max[0] = a[n].Min[0] = a[n].d[0] = x ;
a[n].Min[1] = a[n].Max[1] = a[n].d[1] = y ;
a[n].sum = a[n].z = X ;
a[p].r = n ;
return ;
}
}
}
else {
if(y <= a[p].d[1]) {
if(a[p].l) p = a[p].l ;
else {
n ++ ;
a[n].l = a[n].r = 0 ;
a[n].Max[0] = a[n].Min[0] = a[n].d[0] = x ;
a[n].Min[1] = a[n].Max[1] = a[n].d[1] = y ;
a[n].sum = a[n].z = X ;
a[p].l = n ;
return ;
}
}
else {
if(a[p].r) p = a[p].r ;
else {
n ++ ;
a[n].l = a[n].r = 0 ;
a[n].Max[0] = a[n].Min[0] = a[n].d[0] = x ;
a[n].Min[1] = a[n].Max[1] = a[n].d[1] = y ;
a[n].sum = a[n].z = X ;
a[p].r = n ;
return ;
}
}
}
}
D ^= 1 ;
}
}
bool in_it(int p , int x1,int y11,int x2 , int y2 ){
if(x1 <= a[p].Min[0] && x2 >= a[p].Max[0] && y11 <= a[p].Min[1] && y2 >= a[p].Max[1]) {
return true ;
}
return false ;
}
bool rea_out(int p , int x1 , int y11 , int x2 , int y2 ){
if(x2 < a[p].Min[0] || x1 > a[p].Max[0] || y2 < a[p].Min[1] || y11 > a[p].Max[1]) return true;
return false ;
}
int ans ;
void ask(int p) {
if(rea_out(p , x1 , y11 , x2 , y2)) return ;
if(in_it(p , x1 , y11 , x2 , y2)) {
ans += a[p].sum ;
return ;
}
if(a[p].d[0] >= x1 && a[p].d[0] <= x2 && a[p].d[1] >= y11 && a[p].d[1] <= y2) {
ans += a[p].z ;
}
if(a[p].l){
ask(a[p].l);
}
if(a[p].r){
ask(a[p].r);
}
}
int main(){
scanf("%d",&m);
int op;
int last=0;
n = 0;
while(~scanf("%d",&op)){
if(op == 3)break;
if(op == 1) {
scanf("%d%d%d",&x,&y,&X) ;
x ^= last;
y ^= last;
X ^= last;
if(n == 0) {
n ++ ;
a[n].d[0] = x ; a[n].d[1] = y ;
a[n].z = X ;
a[n].sum = X ;
root = build(1,n,0) ;
}
else {
inse(x,y,X) ;
}
if(n % 5000 == 0) {
root = build(1,n,0) ;
}
}
else {
scanf("%d%d%d%d",&x1,&y11,&x2,&y2) ;
x1 ^= last;
y11 ^= last;
x2 ^= last;
y2 ^= last;
ans = 0;
if(n>0)
ask(root);
else ans = 0 ;
last = ans ;
printf("%d\n",ans) ;
}
}
}

  

BZOJ 4066 kd-tree 矩形询问求和的更多相关文章

  1. BZOJ - 4066 KD树 范围计数 暴力重构

    题意:单点更新,大矩阵(\(n*n,n≤10^5\))求和 二维的KD树能使最坏情况不高于\(O(N\sqrt{N})\) 核心在于query时判断当前子树维护的区间是否有交集/当前子节点是否在块中, ...

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

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

  3. BZOJ 3489: A simple rmq problem(K-D Tree)

    Time Limit: 40 Sec  Memory Limit: 512 MBSubmit: 2579  Solved: 888[Submit][Status][Discuss] Descripti ...

  4. [BZOJ 3221][Codechef FEB13] Obserbing the tree树上询问

    [BZOJ 3221]Obserbing the tree树上询问 题目 小N最近在做关于树的题.今天她想了这样一道题,给定一棵N个节点的树,节点按1~N编号,一开始每个节点上的权值都是0,接下来有M ...

  5. BZOJ 3221: [Codechef FEB13] Obserbing the tree树上询问( 可持久化线段树 + 树链剖分 )

    树链剖分+可持久化线段树....这个一眼可以看出来, 因为可持久化所以写了标记永久化(否则就是区间修改的线段树的持久化..不会), 结果就写挂了, T得飞起...和管理员拿数据调后才发现= = 做法: ...

  6. BZOJ 3053: The Closest M Points(K-D Tree)

    Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1235  Solved: 418[Submit][Status][Discuss] Descripti ...

  7. BZOJ 4520: [Cqoi2016]K远点对(k-d tree)

    Time Limit: 30 Sec  Memory Limit: 512 MBSubmit: 1162  Solved: 618[Submit][Status][Discuss] Descripti ...

  8. BZOJ 1941: [Sdoi2010]Hide and Seek(k-d Tree)

    Time Limit: 16 Sec  Memory Limit: 162 MBSubmit: 1712  Solved: 932[Submit][Status][Discuss] Descripti ...

  9. BZOJ 2648: SJY摆棋子(K-D Tree)

    Time Limit: 20 Sec  Memory Limit: 128 MBSubmit: 6051  Solved: 2113[Submit][Status][Discuss] Descript ...

随机推荐

  1. iOS学习笔记(一)——ios搭建开发环境

    好久就想试水IOS开发了,由于开发环境限制,一直局限于理论和虚拟机,近来入手了MacBook Pro,也来尝尝鲜,笔者也是现学现总结,如果有不足,请指正. IOS开发必备MAC OS X 另加一部iP ...

  2. hdu 5185(DP)

    不错的一道dp题目,一开始想了一种N*N的dp,后面就一直想怎么优化,然后就一直都在坑中了. 这题题解还是看早了,应该再多想会的,多换种表示状态的方法再想想. dp[i][j]=dp[i-j][j]+ ...

  3. Ants(二分图最佳完美匹配)

    Ants Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 6904   Accepted: 2164   Special Ju ...

  4. 前端 为什么我选择用框架而不是Jquery

    对于很多习惯用Jquery的前端甚至后端,都很不解,为什么不用Jquery而是框架.觉得框架学起来麻烦,成本高,今天我以我浅薄的知识来总结一下为什么前台开发选择用框架: 前台开发,主要的性能是卡在回流 ...

  5. 巨蟒python全栈开发linux之cento9

    1.docker入门学习 查看机器中已经启动的所有的进程. ps -ef 2.docker常用命令学习 3.docker学习3 4.dockerfile与镜像 5.docker私有仓库 6.rabbi ...

  6. 巨蟒python全栈开发django7:多表增加和查询

    1.回顾内容&&补充 补充1: 补充2: 这个选择的是第二个解释器. 选择第一个的话,只是针对当前的项目,如果再开新项目的话,需要重新下载安装相关的包. 点击保存,因为我们注释掉了,创 ...

  7. 超详细:CSS-float详解

    Float 详解 本文摘自:http://www.cnblogs.com/yuanchenqi/articles/5615774.html 首先要知道,div是块级元素,在页面中独占一行,自上而下排列 ...

  8. mprotect() failed: Cannot allocate memory

    遇到这个问题是在測试项目的性能时发现的,每一个对象分配一页大小的空间然后mprotect() 保护起来,当系统分配3W多个页的时候会出现这个问题. google到在一份邮件列表中也曾提到该问题.htt ...

  9. Mybatis使用pageHelper步骤

    1.在pom.xml中添加如下依赖: <dependency> <groupId>com.github.pagehelper</groupId> <artif ...

  10. Android Studio的快捷键

    Android Studio可以在setting的keymaps设置快捷键,但最好使用该默认的快捷键. 生成TAG: logt 控制台打印带参的log:logm 代码提示:ctrl + alt + s ...