传送门

题意:

先有两种操作,插入和查询,插入操作则插入一个点\((x,y,z)\),查询操作给出两个点\((x_1,y_1,z_1),(x_2,y_2,z_2)\),回答满足\(x_1\leq x\leq x_2,y_1\leq y\leq y_2,z_1\leq z\leq z_2\)的\((x,y,z)\)的个数为多少。

思路:

就是带修改的四维偏序问题。

首先我们可以将每个点看作三维空间中的一个点,那么每次询问就相当于询问立方体中的点。

我们将询问拆成\(8\)个询问,那么每次解决的就是一个前缀和问题,也就是满足\(x\leq x_0,y\leq y_0,z\leq z_0\)的点的个数。

那么就对一维排序,之后\(cdq\)套\(cdq\)再套个树状数组就好啦。

注意我们现在只有左边区间的修改操作才会对右边区间的询问操作有影响~

注意一下空间,要开大点。

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 50005; int T, q; struct node{
int x, y, z, op, id, part;
}a[N * 10], b[N * 10], d[N * 10]; int hs[N << 2]; bool isq[N];
int ans[N]; int c[N << 2];
int lowbit(int x) {return x & (-x);} void update(int x, int v) {
for(; x < N << 2; x += lowbit(x)) c[x] += v;
} int query(int x) {
int ans = 0;
for(; x; x -= lowbit(x)) ans += c[x];
return ans;
} void cdq2(int l, int r) {
if(l == r) return ;
int mid = (l + r) >> 1;
cdq2(l, mid); cdq2(mid + 1, r);
int t1 = l, t2 = mid + 1;
for(int i = l; i <= r; i++) {
if(t2 > r || (t1 <= mid && b[t1].y <= b[t2].y)) {
if(b[t1].part == 0 && b[t1].op == 0) {
update(b[t1].z, 1);
}
d[i] = b[t1++];
} else {
if(b[t2].part && b[t2].op != 0) {
ans[b[t2].id] += b[t2].op * query(b[t2].z);
}
d[i] = b[t2++];
}
}
for(int i = l; i <= mid; i++) {
if(b[i].part == 0 && b[i].op == 0) update(b[i].z, -1);
}
for(int i = l; i <= r; i++) b[i] = d[i];
} void cdq(int l, int r) {
if(l == r) return ;
int mid = (l + r) >> 1;
cdq(l, mid); cdq(mid + 1, r);
int t1 = l, t2 = mid + 1;
for(int i = l; i <= r; i++) {
if(t2 > r || (t1 <= mid && a[t1].x <= a[t2].x)) {
b[i] = a[t1++];
b[i].part = 0;
} else {
b[i] = a[t2++];
b[i].part = 1;
}
}
for(int i = l; i <= r; i++) a[i] = b[i];
cdq2(l, r);
} int main() {
// freopen("input.in", "r", stdin);
ios::sync_with_stdio(false); cin.tie(0);
cin >> T;
while(T--) {
cin >> q;
for(int i = 1; i <= q; i++) ans[i] = 0, isq[i] = false;
int cnt = 0; hs[0] = 0;
for(int i = 1; i <= q; i++) {
int op; cin >> op;
if(op == 1) {
int x, y, z; cin >> x >> y >> z;
a[++cnt] = {x, y, z, 0, i, -1};
hs[++hs[0]] = z;
} else {
isq[i] = true;
int x1, y1, z1, x2, y2, z2;
cin >> x1 >> y1 >> z1 >> x2 >> y2 >> z2;
--x1, --y1, --z1;
a[++cnt] = {x1, y1, z1, -1, i, -1};
a[++cnt] = {x1, y2, z1, 1, i, -1};
a[++cnt] = {x2, y2, z1, -1, i, -1};
a[++cnt] = {x2, y1, z1, 1, i, -1};
a[++cnt] = {x1, y1, z2, 1, i, -1};
a[++cnt] = {x1, y2, z2, -1, i, -1};
a[++cnt] = {x2, y2, z2, 1, i, -1};
a[++cnt] = {x2, y1, z2, -1, i, -1};
hs[++hs[0]] = z1, hs[++hs[0]] = z2;
}
}
sort(hs + 1, hs + hs[0] + 1);
hs[0] = unique(hs + 1, hs + hs[0] + 1) - hs - 1;
for(int i = 1; i <= cnt; i++) a[i].z = lower_bound(hs + 1, hs + hs[0] + 1, a[i].z) - hs;
cdq(1, cnt);
for(int i = 1; i <= q; i++) {
if(isq[i]) cout << ans[i] << '\n';
}
}
return 0;
}

最新文章

  1. Asp.Net MVC+BootStrap+EF6.0实现简单的用户角色权限管理1
  2. [CareerCup] 6.4 Blue Eyes People on Island 岛上的蓝眼人
  3. 50 个最棒的 jQuery 日历插件,很齐全了!(转)
  4. cocos2d-x项目过程记录(cocos2d-x的新知)
  5. boost.asio系列——Timer
  6. 【PHP】PHP从入门到精通(一)——想学习PHP的小伙伴的福利来了!
  7. TCP/IP协议栈 --- IP路由
  8. app优化篇
  9. 《Inside C#》笔记(十三) 多线程 上
  10. context configure and clock schedule
  11. gooreplacer 很好用
  12. node-webkit学习(2)基本结构和配置
  13. 〖Android〗Android源代码所有目录生成的Target(编译生成文件反查)
  14. Android 获取联系人和电话号码
  15. 随手练——HDU 5015 矩阵快速幂
  16. 用iptables做代理
  17. CentOS6.5下Apache防止目录遍历
  18. 求给出第 K个 N位二进制数,该二进制数不得有相邻的“1”
  19. Regexp:template
  20. oracle 推断字符是否为字母

热门文章

  1. ASP.NET Core MVC 中的 Model 模型
  2. Linux性能优化实战学习笔记:第九讲
  3. Linux性能优化实战学习笔记:第三十七讲
  4. Java程序进行调优及监控
  5. 服务器个人环境下pytorch0.4.1编译warp-ctc遇到的问题及解决方法
  6. 初识Go语言--(2)Hello World
  7. AngularJS入门Demo
  8. CyclicBarrier一组线程相互等待
  9. Window 远程桌面漏洞风险,各个厂家的扫描修复方案(CVE-2019-0708)
  10. Java学习:方法的引用