题目描述

你有一个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

终止程序

 
 

输入

输入文件第一行一个正整数N。
接下来每行一个操作。每条命令除第一个数字之外,均要异或上一次输出的答案last_ans,初始时last_ans=0。

输出

对于每个2操作,输出一个对应的答案。

样例输入

4
1 2 3 3
2 1 1 3 3
1 1 1 1
2 1 1 0 7
3

样例输出

3
5


题解

KD-tree

题目强制在线,所以不能离线分治;平面上问题,可以用KD-tree来解决。

具体来说大部分都是板子,只有查询时有点变化,类似于 线段树/平衡树 的区间查询,不断缩小范围。

然而这样裸上亲测会TLE,究其原因是KD-tree的退化。

所以每次加入一定数目的点后,我们需要将KD-tree重构,类似于朝鲜树(实际替罪羊树式重构更为高效,这里懒了)。

这样能够使得树高不会特别离谱,然后就可以过了。

#include <cstdio>
#include <cstring>
#include <algorithm>
#define N 500010
using namespace std;
struct data
{
int p[2] , maxn[2] , minn[2] , c[2] , w , sum;
}a[N];
int d , root;
bool cmp(data a , data b)
{
return a.p[d] == b.p[d] ? a.p[d ^ 1] < b.p[d ^ 1] : a.p[d] < b.p[d];
}
void pushup(int k , int s)
{
a[k].maxn[0] = max(a[k].maxn[0] , a[s].maxn[0]);
a[k].minn[0] = min(a[k].minn[0] , a[s].minn[0]);
a[k].maxn[1] = max(a[k].maxn[1] , a[s].maxn[1]);
a[k].minn[1] = min(a[k].minn[1] , a[s].minn[1]);
a[k].sum += a[s].sum;
}
int build(int l , int r , int now)
{
int mid = (l + r) >> 1;
d = now , nth_element(a + l , a + mid , a + r + 1 , cmp);
a[mid].maxn[0] = a[mid].minn[0] = a[mid].p[0];
a[mid].maxn[1] = a[mid].minn[1] = a[mid].p[1];
a[mid].sum = a[mid].w;
a[mid].c[0] = a[mid].c[1] = 0;
if(l < mid) a[mid].c[0] = build(l , mid - 1 , now ^ 1) , pushup(mid , a[mid].c[0]);
if(r > mid) a[mid].c[1] = build(mid + 1 , r , now ^ 1) , pushup(mid , a[mid].c[1]);
return mid;
}
void ins(int x)
{
int *t = &root;
d = 0;
while(*t) pushup(*t , x) , t = &a[*t].c[a[x].p[d] > a[*t].p[d]] , d ^= 1;
*t = x;
}
int query(int k , int x1 , int y1 , int x2 , int y2)
{
if(!k || a[k].maxn[0] < x1 || a[k].maxn[1] < y1 || a[k].minn[0] > x2 || a[k].minn[1] > y2) return 0;
if(a[k].maxn[0] <= x2 && a[k].maxn[1] <= y2 && a[k].minn[0] >= x1 && a[k].minn[1] >= y1) return a[k].sum;
int ans = 0;
if(a[k].p[0] >= x1 && a[k].p[0] <= x2 && a[k].p[1] >= y1 && a[k].p[1] <= y2) ans += a[k].w;
ans += query(a[k].c[0] , x1 , y1 , x2 , y2) + query(a[k].c[1] , x1 , y1 , x2 , y2);
return ans;
}
int main()
{
int opt , x1 , y1 , x2 , y2 , last = 0 , tot = 0;
scanf("%*d");
while(scanf("%d" , &opt) != EOF && opt != 3)
{
if(opt == 1)
{
tot ++ , scanf("%d%d%d" , &a[tot].p[0] , &a[tot].p[1] , &a[tot].w);
a[tot].p[0] ^= last , a[tot].p[1] ^= last , a[tot].w ^= last , a[tot].sum = a[tot].w;
a[tot].maxn[0] = a[tot].minn[0] = a[tot].p[0];
a[tot].maxn[1] = a[tot].minn[1] = a[tot].p[1];
ins(tot);
if(tot % 10000 == 0) root = build(1 , tot , 0);
}
else scanf("%d%d%d%d" , &x1 , &y1 , &x2 , &y2) , x1 ^= last , y1 ^= last , x2 ^= last , y2 ^= last , printf("%d\n" , last = query(root , x1 , y1 , x2 , y2));
}
return 0;
}

【bzoj4066】简单题 KD-tree的更多相关文章

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

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

  2. P4148 简单题 k-d tree

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

  3. [BZOJ2683][BZOJ4066]简单题

    [BZOJ2683][BZOJ4066]简单题 试题描述 你有一个N*N的棋盘,每个格子内有一个整数,初始时的时候全部为0,现在需要维护两种操作: 命令 参数限制 内容 1 x y A 1<=x ...

  4. bzoj4066: 简单题 K-Dtree

    bzoj4066: 简单题 链接 bzoj 思路 强制在线.k-dtree. 卡常啊.空间开1e6就T了. 代码 #include <bits/stdc++.h> #define my_m ...

  5. Bzoj4066 简单题

    Time Limit: 50 Sec  Memory Limit: 20 MBSubmit: 2185  Solved: 581 Description 你有一个N*N的棋盘,每个格子内有一个整数,初 ...

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

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

  7. BZOJ4066 简单题(KD-Tree)

    板子题. #include<iostream> #include<cstdio> #include<cmath> #include<cstdlib> # ...

  8. 【kd-tree】bzoj4066 简单题

    同p1176. #include<cstdio> #include<cmath> #include<algorithm> using namespace std; ...

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

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

  10. 初涉k-d tree

    听说k-d tree是一个骗分的好东西?(但是复杂度差评??? 还听说绍一的kdt常数特别小? KDT是什么 KDT的全称是k-degree tree,顾名思义,这是一种处理多维空间的数据结构. 例如 ...

随机推荐

  1. Hybrid App开发之css样式使用

    前言: 前面学习了html,今天学习一下css的基本使用,看下html与css之间是如何结合来编写前端网页的. CSS 是什么? CSS 是 Cascading Style Sheets(级联样式表) ...

  2. python3安装pip

    wget --no-check-certificate https://pypi.python.org/packages/source/p/pip/pip-8.0.2.tar.gz#md5=3a73c ...

  3. mantis基本配置及邮件服务器配置

    邮件服务器配置 在c:\php-5.0.3\php.ini文件中查找smtp,将localhost改为你的发件服务器,如SMTP = smtp.163.com   在php.ini文件中查找sendm ...

  4. JZTK项目 驾照题库项目servlet层得到的json字符串在浏览器中 汉字部分出现问号?无法正常显示的解决方法

    servlet层中的代码如下: package com.swift.jztk.servlet; import java.io.IOException; import javax.servlet.Ser ...

  5. A1020 Tree Traversals (25 分)

    Suppose that all the keys in a binary tree are distinct positive integers. Given the postorder and i ...

  6. Ajax基础知识梳理

    Ajax用一句话来说就是无须刷新页面即可从服务器取得数据.注意,虽然Ajax翻译过来叫异步JavaScript与XML,但是获得的数据不一定是XML数据,现在服务器端返回的都是JSON格式的文件. 完 ...

  7. Memory loss【记忆缺失】

    Memory Loss Losing your ability to think and remember is pretty scary. We know the risk of dementia ...

  8. 在virtualBox中打开vdi(转载)

    在VirtualBox中启动“新建虚拟机”向导.第一步,输入名称“ubuntu”,选择系统类型为“Linux 2.6”.第二步,内存大小默认是256MB,不变.第三步,虚拟硬盘,点击按钮“现有”,在新 ...

  9. 洛谷 P3740 [HAOI2014]贴海报

    题目描述 Bytetown城市要进行市长竞选,所有的选民可以畅所欲言地对竞选市长的候选人发表言论.为了统一管理,城市委员会为选民准备了一个张贴海报的electoral墙. 张贴规则如下: electo ...

  10. 3、python中的字符串

    一.前言 字符串是python中重要的数据类型.字符串就是一段文本,在python中用引号来标示. 二.字符串分类 字符串根据使用场景不同,一共分成3类: (1)单引号.双引号创建的单行字符串: 在单 ...