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;
}
转载于:https://www.cnblogs.com/water-mi/p/10172376.html
Luogu P4148 简单题(K-D Tree)相关推荐
- leetcode python3 简单题101. Symmetric Tree
1.编辑器 我使用的是win10+vscode+leetcode+python3 环境配置参见我的博客: 链接 2.第一百零一题 (1)题目 英文: Given a binary tree, chec ...
- leetcode python3 简单题100. Same Tree
1.编辑器 我使用的是win10+vscode+leetcode+python3 环境配置参见我的博客: 链接 2.第一百题 (1)题目 英文: Given two binary trees, wri ...
- P4148 简单题(KDTree)
传送门 KDTree 修改权值当做插入节点,不平衡就暴力重构,询问的时候判断当前节点代表的矩形是否在询问的矩形的,是的话返回答案,相离返回0,否则的话判断当前点是否在矩形内,然后继续递归下去 //mi ...
- PythonJava版【LeetCode】简单题答案整理01
不得不开始刷LeetCode了,为了使小白的自尊心不受到毁灭性的打击,所以打算从最简单的题开始刷.现把所有题目的Python和Java代码都放在这儿,以便随时回忆.分两种语言的原因在于,Python是 ...
- 【bzoj2751】[HAOI2012]容易题(easy) 数论,简单题
Description 为了使得大家高兴,小Q特意出个自认为的简单题(easy)来满足大家,这道简单题是描述如下: 有一个数列A已知对于所有的A[i]都是1~n的自然数,并且知道对于一些A[i]不能取 ...
- BZOJ4066: 简单题
BZOJ4066: 简单题 Description 你有一个N*N的棋盘,每个格子内有一个整数,初始时的时候全部为0,现在需要维护两种操作: 命令 参数限制 内容 1 x y A 1<=x,y& ...
- BZOJ 4066: 简单题
4066: 简单题 Time Limit: 50 Sec Memory Limit: 20 MB Submit: 2373 Solved: 622 [Submit][Status][Discuss ...
- CSU 1785: 又一道简单题
1785: 又一道简单题 Submit Page Summary Time Limit: 5 Sec Memory Limit: 128 Mb Submitted: 602 ...
- zzuli 2177 Contest - 河南省多校连萌(四)(简单题)
Contest - 河南省多校连萌(四) Problem F: 小姐姐的忠告:少吃辣条多刷题 题目链接 Time Limit: 1 Sec Memory Limit: 128 MB Submit: 1 ...
最新文章
- makefile 和shell文件相互调用
- 灰度重采样(Gray Resampling
- 重温《数据库系统概论》【第一篇 基础篇】【第2章 关系数据库】
- 在linux中 如何创建磁盘配额,如何在Linux系统中配置磁盘配额?
- 上拉电阻与下拉电阻介绍
- 计算机网络运输层两种服务,计算机网络体系结构及协议之运输层
- 主机一拖二 linux,使opensuse12.1实现一拖二(拖机)的双人使用系统(上)
- 前端特效,超级炫酷,内容丰富,多种选择
- Windows XP DOS命令大全
- DNS域名解析协议详解
- Flutter Convex Bottom 底部导航
- [转载]看我花式绕过校园网计费认证
- Traffic Shifting
- ceph-deploy源码分析(三)——mon模块 转
- Linux SSH命令大全
- 《杰克.韦尔奇自传》读书笔记
- 100阶乘的约数个数
- 关于Xilinx Docnav 使用这些事
- BUG计算机术语,词汇 | 为什么要称程序的错误为Bug?
- 从MP3ID3v2标签读出附加图片(专辑封面)
热门文章
- mysql+web日志分析工具_用Python+MySQL实现2017年web日志分析报告
- php uid gid,用户信息,函数介绍,PHP开源CMS系统帮助文档
- 【转】Linux的僵尸进程解决攻略
- 一张图读懂MVC设计模式,从用户发起请求到获取响应,应用内部到底是如何数据流转、业务串联的
- 开源GIS(十四)——openlayers通过geoserver中WFS更改要素
- 在C#中获取如PHP函数time()一样的时间戳
- 关于AIR 应用程序沙箱
- Android常用Adapter用例
- Memcache分组和同步机制的实现
- aix c语言 构造函数,错误:命名构造函数,而不是类型。使用g++4.6.1进行编译