Luogu P4148 简单题(K-D Tree)
题面
题解
因为强制在线,所以我们不能$cdq$分治,所以考虑用$KDT$,$KDT$维护一个矩阵,然后询问的时候如果当前矩形在询问区间内,直接记贡献,否则判断当前点是否在矩阵内,然后左右分别递归下去判断就行了。
#include <cstdio>
#include <cstring>
#include <algorithm>
using std::min; using std::max;
using std::nth_element;
typedef long long ll;
template<typename T>
void read(T &x) {
int flag = 1; x = 0; char ch = getchar();
while(ch < '0' || ch > '9') { if(ch == '-') flag = -flag; ch = getchar(); }
while(ch >= '0' && ch <= '9') x = x * 10 + ch - '0', ch = getchar(); x *= flag;
}
const int N = 200005;
int n, x1, x2, y1, y2, k, ans, rt, WD, top, cnt, rub[N];
struct poi { int x[2], w; } p[N];
struct node { int mi[2], mx[2], sum, lc, rc, siz; poi tp; } t[N];
int operator < (const poi &a, const poi &b) { return a.x[WD] < b.x[WD]; }
inline int newnode() { if(top) return rub[top--]; else return ++cnt; }
void up(int k) {
int l = t[k].lc, r = t[k].rc;
for(int i = 0; i < 2; ++i) {
t[k].mi[i] = t[k].mx[i] = t[k].tp.x[i];
if(l) t[k].mi[i] = min(t[k].mi[i], t[l].mi[i]), t[k].mx[i] = max(t[k].mx[i], t[l].mx[i]);
if(r) t[k].mi[i] = min(t[k].mi[i], t[r].mi[i]), t[k].mx[i] = max(t[k].mx[i], t[r].mx[i]);
}
t[k].sum = t[l].sum + t[r].sum + t[k].tp.w, t[k].siz = t[l].siz + t[r].siz + 1;
}
int build(int l, int r, int wd) {
if(l > r) return 0;
int mid = (l + r) >> 1, k = newnode();
WD = wd, nth_element(p + l, p + mid, p + r + 1), t[k].tp = p[mid];
t[k].lc = build(l, mid - 1, wd ^ 1), t[k].rc = build(mid + 1, r, wd ^ 1);
up(k); return k;
}
void pia(int k, int num) {
if(t[k].lc) pia(t[k].lc, num);
p[t[t[k].lc].siz + num + 1] = t[k].tp, rub[++top] = k;
if(t[k].rc) pia(t[k].rc, num + t[t[k].lc].siz + 1);
}
void check(int &k, int wd) {
if(0.75 * t[k].siz < t[t[k].lc].siz || 0.75 * t[k].siz < t[t[k].rc].siz)
pia(k, 0), k = build(1, t[k].siz, wd);
}
void insert(int &k, poi tmp, int wd) {
if(!k) { k = newnode(), t[k].lc = t[k].rc = 0, t[k].tp = tmp, up(k); return ; }
if(tmp.x[wd] <= t[k].tp.x[wd]) insert(t[k].lc, tmp, wd ^ 1);
else insert(t[k].rc, tmp, wd ^ 1);
up(k), check(k, wd);
}
int in(int x1,int y1,int x2,int y2,int X1,int Y1,int X2,int Y2) { return (X1>=x1&&X2<=x2&&Y1>=y1&&Y2<=y2); }
int out(int x1,int y1,int x2,int y2,int X1,int Y1,int X2,int Y2) { return (x1>X2||x2<X1||y1>Y2||y2<Y1); }
int query(int k, int x1, int y1, int x2 ,int y2) {
if(!k) return 0;
int ret = 0;
if(in(x1, y1, x2, y2, t[k].mi[0], t[k].mi[1], t[k].mx[0], t[k].mx[1])) return t[k].sum;
if(out(x1, y1, x2, y2, t[k].mi[0], t[k].mi[1], t[k].mx[0], t[k].mx[1])) return 0;
if(in(x1, y1, x2, y2, t[k].tp.x[0], t[k].tp.x[1], t[k].tp.x[0], t[k].tp.x[1])) ret += t[k].tp.w;
return ret + query(t[k].lc, x1, y1, x2, y2) + query(t[k].rc, x1, y1, x2, y2);
}
int main () {
read(n);
while(true) {
int opt; read(opt);
if(opt == 3) break;
else {
read(x1), read(y1), x1 ^= ans, y1 ^= ans;
if(opt == 1) read(k), insert(rt, (poi){x1, y1, k ^ ans}, 0);
else {
read(x2), read(y2), x2 ^= ans, y2 ^= ans;
ans = query(rt, x1, y1, x2, y2), printf("%d\n", ans);
}
}
}
return 0;
}
Luogu P4148 简单题(K-D Tree)的更多相关文章
- luogu P4148 简单题
传送门 这题真简单,直接把\(CDQ\)给ban掉了 其实数据范围比较小可以直接二维树状数组,我们看数据范围,发现点的个数比N还小,可以考虑用一些奇怪的数据结构 说的就是你,\(KD tree\) \ ...
- 洛谷 P4148 简单题 解题报告
P4148 简单题 题意 维护单点加与矩形求和,强制在线 说明 \(n\le 500000,m\le 200000\),\(4000ms / 20MB\) kd-tree 复杂度我不懂 是一颗平衡树, ...
- 洛谷 P4148 简单题 KD-Tree 模板题
Code: //洛谷 P4148 简单题 KD-Tree 模板题 #include <cstdio> #include <algorithm> #include <cst ...
- 简单题(K-D Tree)
简单题不简单-- 我们把单点加操作改成插入一个权值为增加量的点,将问题转化成询问一个矩阵中所有点的和,用 \(K-D\ Tree\) 维护,时间复杂度 \(O(n\sqrt{n})\) \(Code\ ...
- P4148 简单题 k-d tree
思路:\(k-d\ tree\) 提交:2次 错因:整棵树重构时的严重错误:没有维护父子关系(之前写的是假重构所以没有维护父子关系) 题解: 遇到一个新的点就插进去,如果之前出现过就把权值加上. 代码 ...
- P4148 简单题(KDTree)
传送门 KDTree 修改权值当做插入节点,不平衡就暴力重构,询问的时候判断当前节点代表的矩形是否在询问的矩形的,是的话返回答案,相离返回0,否则的话判断当前点是否在矩形内,然后继续递归下去 //mi ...
- BZOJ4066:简单题(K-D Tree)
Description 你有一个N*N的棋盘,每个格子内有一个整数,初始时的时候全部为0,现在需要维护两种操作: 命令 参数限制 内容 1 x y A 1<=x,y<=N,A是正整数 ...
- acm.njupt 1001-1026 简单题
点击可展开上面目录 Acm.njupt 1001-1026简单题 第一页许多是简单题,每题拿出来说说,没有必要,也说不了什么. 直接贴上AC的代码.初学者一题题做,看看别人的AC代码,寻找自己的问题. ...
- [BZOJ 3110] [luogu 3332] [ZJOI 2013]k大数查询(权值线段树套线段树)
[BZOJ 3110] [luogu 3332] [ZJOI 2013]k大数查询(权值线段树套线段树) 题面 原题面有点歧义,不过从样例可以看出来真正的意思 有n个位置,每个位置可以看做一个集合. ...
随机推荐
- Codeforces Round #380 (Div. 2)/729E Subordinates 贪心
There are n workers in a company, each of them has a unique id from 1 to n. Exaclty one of them is a ...
- 三星 C7恢复 出厂设置
http://jingyan.baidu.com/article/c14654134f0fd20bfcfc4c1e.html
- 「6月雅礼集训 2017 Day11」tree
[题目大意] 给出一棵带权树,有两类点,一类黑点,一类白点. 求切断黑点和白点间路径的最小代价. $n \leq 10^5$ [题解] 直接最小割能过..但是树形dp明显更好写 设$f_{x,0/1/ ...
- 崩坏3mmd中的渲染技术研究
http://youxiputao.com/articles/11839 主要是参考该篇文章做一个微小的复盘. 漫反射与高光 文章中的漫反射与高光并不是类似于普通的 resultCol = Diffu ...
- F题 hdu 1431 素数回文
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1431 素数回文 Time Limit: 2000/1000 MS (Java/Others) M ...
- Android跳转到拨打电话的页面
在Android6.0之后,拨打电话需要用户授予动态权限,项目中有此需求,有一种简单的方法,直接携带电话号码跳转到系统拨打电话的页面,很多应用也是这么做的,这样可以减轻工作量 代码如下: Androi ...
- perl6 修改文件并覆盖
use v6; my $filename = 'data.txt'; my $data = slurp $filename; say $data; $data ~~ s/'4'/'ABC'/; say ...
- rabbitmq之队列性能测试及优化方法(六)
前言 下面关注一下rabbitmq实际使用时的性能问题和怎么进行一些优化. 性能测试 针对每个需要生产/消费者与rabbitmq进行通讯的方法进行测试 测试环境 排除网络IO的干扰,采用生产者和消费者 ...
- Linux中查看进程占用内存的情况【转】
转自:http://hutaow.com/blog/2014/08/28/display-process-memory-in-linux/ Linux中查看某个进程占用内存的情况,执行如下命令即可,将 ...
- python基础===解决python3 UnicodeEncodeError: 'gbk' codec can't encode character '\xXX' in position XX(转载)
本文转自:解决python3 UnicodeEncodeError: 'gbk' codec can't encode character '\xXX' in position XX 从网上抓了一些字 ...