题目传送门

题意:在一个星空中,按着时间会出现一些点,现在john想知道,在某个时间内有多少个星星是的坐标是满足条件的。(x1<=x<=x2, y1 <= y <= y2, z1 <= z <= z2).
题解:先简化问题,如果我们就统计出现所有 x <= x2 , y <= y2, z <= z2的点的话,这就是一个4维偏序题。

对于这个统计点数来说, 我们先按照题目给定点的顺序来进行CDQ, 这样在CDQ内只有左边的添加点会对右边的询问点产生影响,然后我们再把这些会对答案找出影响的点拿出来,

对这些点进行关于X轴内一个sort,对于sort完的结果,我们再进行cdq, 这样在cdq内还是只有左边的左边的添加点会对右边的询问点产生影响,然后我们再把这些会对答案找出影响的点拿出来。

这样就变成了2维偏序题了, 再对y sort, 然后for一遍询问答案把答案加进去就好了。

现在的问题就变成了怎么询问这个长方体内点的个数。 我们可以用差分的思想去维护这个矩形。

我们对一次询问可以拆成8次询问。

Q1( X1-1, Y1-1, Z2) Q2 (X1-1, Y2, Z2) Q3 (X2, Y1-1, Z2) Q4(X2,Y2,Z2)

Q5( X1-1, Y1-1, Z1-1) Q6 (X1-1, Y2, Z1-1) Q7 (X2, Y1-1, Z1-1) Q8(X2,Y2,Z1-1)

可以发现 Q1-Q2-Q3+Q4 得到的是  z <= z2    x1<=x <= x2 && y1 <= y <= y2 的点的个数和。

现在我们在减去 z <= z1-1 x1<=x <= x2 && y1 <= y <= y2 的个数和就是答案了。

在CDQ的过程中, 我们可以加上一个剪枝 即对于这个CDQ来说,如果左边没有添加点 或者 右边没有询问点 就再进行处理了, 因为不会对答案造成影响。

代码:

 #include<bits/stdc++.h>
using namespace std;
#define Fopen freopen("_in.txt","r",stdin); freopen("_out.txt","w",stdout);
#define LL long long
#define ULL unsigned LL
#define fi first
#define se second
#define pb push_back
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define lch(x) tr[x].son[0]
#define rch(x) tr[x].son[1]
#define max3(a,b,c) max(a,max(b,c))
#define min3(a,b,c) min(a,min(b,c))
typedef pair<int,int> pll;
const int inf = 0x3f3f3f3f;
const LL INF = 0x3f3f3f3f3f3f3f3f;
const LL mod = (int)1e9+;
const int N = 1e6 + ;
struct Node{
int x, y, z, op, id;
}A[N], B[N], C[N];
int ans[N];
int zz[N];
int tot = ;
int zsz;
int bit[N];
void add(int x, int v){
while(x <= zsz){
bit[x] += v;
x += x & (-x);
}
}
int query(int x){
int ret = ;
while(x > ){
ret += bit[x];
x -= x & (-x);
}
return ret;
}
bool cmp_x(Node & n1, Node & n2){
if(n1.x != n2.x) return n1.x < n2.x;
if(n1.y != n2.y) return n1.y < n2.y;
if(n1.z != n2.z) return n1.z < n2.z;
return n1.id < n2.id;
}
bool cmp_y(Node & n1, Node & n2){
if(n1.y != n2.y) return n1.y < n2.y;
if(n1.z != n2.z) return n1.z < n2.z;
return n1.id < n2.id;
}
void cdq(int l, int r){
if(l >= r) return ;
int m = l+r >> ;
cdq(l, m); cdq(m+, r);
int k = ;
for(int i = l; i <= m; i++)
if(!B[i].id) C[++k] = B[i];
for(int i = m+; i <= r; i++)
if(B[i].id) C[++k] = B[i];
if(C[].id != || C[k].id == ) return ;/// 剪枝
sort(C+, C++k, cmp_y);
for(int i = ; i <= k; i++){
if(C[i].op)
ans[C[i].id] += query(C[i].z) * C[i].op;
else
add(C[i].z, );
}
for(int i = ; i <= k; i++){
if(C[i].op);
else add(C[i].z, -);
}
}
void CDQ(int l, int r){
if(l == r) return ;
int m = l+r >> ;
CDQ(l,m); CDQ(m+,r);
int k = ;
for(int i = l; i <= m; i++)
if(!A[i].id) B[++k] = A[i];
for(int i = m+; i <= r; i++)
if(A[i].id) B[++k] = A[i];
if(B[].id != || B[k].id == ) return ;/// 剪枝
sort(B+, B++k, cmp_x);
cdq(,k);
} inline void nownode(int x, int y, int z, int op, int id){
++tot; A[tot].x = x; A[tot].y = y; zz[tot] = z;
A[tot].z = z; A[tot].op = op; A[tot].id = id;
}
int main(){
int T;
scanf("%d", &T);
while(T--){
int n, op, x1, y1, z1, x2, y2, z2, m = ;
tot = ;
scanf("%d", &n);
for(int i = ; i <= n; i++){
scanf("%d", &op);
if(op == ){
scanf("%d%d%d", &x1, &y1, &z1);
nownode(x1, y1, z1, , );
}
else {
m++;
ans[m] = ;
scanf("%d%d%d", &x1, &y1, &z1);
scanf("%d%d%d", &x2, &y2, &z2);
nownode(x2,y2,z2,,m);
nownode(x1-,y1-,z2,,m);
nownode(x2,y1-,z2,-,m);
nownode(x1-,y2,z2,-,m); nownode(x2,y2,z1-,-,m);
nownode(x1-,y1-,z1-,-,m);
nownode(x2,y1-,z1-,,m);
nownode(x1-,y2,z1-,,m);
}
}
sort(zz+, zz+tot+);
zsz = unique(zz+, zz+tot+) - zz - ;
for(int i = ; i <= tot; i++)
A[i].z = lower_bound(zz+, zz++zsz, A[i].z) - zz;
CDQ(, tot);
for(int i = ; i <= m; i++)
printf("%d\n", ans[i]);
}
return ;
}

HDU 5126 stars 4维偏序, CDQ套CDQ的更多相关文章

  1. HDU - 5126: stars (求立方体内点数 CDQ套CDQ)

    题意:现在给定空空的三维平面,有加点操作和询问立方体点数. 思路:考虑CDQ套CDQ.复杂度是O(NlogN*logN*logN),可以过此题. 具体的,这是一个四维偏序问题,4维分别是(times, ...

  2. cogs2479 偏序(CDQ套CDQ)

    题目链接 思路 四维偏序 \(CDQ\)套\(CDQ\),第一维默认有序.第二维用第一个\(CDQ\)变成有序的.并且对每个点标记上第一维属于左边还是右边.第二个\(CDQ\)处理第三维,注意两个\( ...

  3. [HZOI 2016] 偏序(CDQ套CDQ)

    传送门 思路: 就是cdq套cdq的模板题 #include <bits/stdc++.h> using namespace std; typedef long long ll; cons ...

  4. HDU5126---stars (CDQ套CDQ套 树状数组)

    题意:Q次操作,三维空间内 每个星星对应一个坐标,查询以(x1,y1,z1) (x2,y2,z2)为左下顶点 .右上顶点的立方体内的星星的个数. 注意Q的范围为50000,显然离散化之后用三维BIT会 ...

  5. 【教程】CDQ套CDQ——四维偏序问题

    前言 上一篇文章已经介绍了简单的CDQ分治,包括经典的二维偏序和三维偏序问题,还有带修改和查询的二维/三维偏序问题.本文讲介绍多重CDQ分治的嵌套,即多维偏序问题. 四维偏序问题       给定N( ...

  6. 四维偏序 CDQ套CDQ

    对CDQ深一步的理解 昨天做了一道CDQ,看了一堆CDQ可做的题,今天又做了一道四维偏序 感觉对CDQ的理解又深了一点,故来写一写现在自己对于CDQ的理解 CDQ其实就是实现了这样的一个问题的转化: ...

  7. hdu 5126 stars (四维偏序,离线,CDQ套CDQ套树状数组)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5126 思路:支持离线,那么我们可以用两次CDQ分治使四维降为二维,降成二维后排个序用树状数组维护下就好 ...

  8. hdu 5126 stars cdq分治套cdq分治+树状数组

    题目链接 给n个操作, 第一种是在x, y, z这个点+1. 第二种询问(x1, y1, z1). (x2, y2, z2)之间的总值. 用一次cdq分治可以将三维变两维, 两次的话就变成一维了, 然 ...

  9. HDU - 5126 stars (CDQ分治)

    题目链接 题目大意:一共有Q(1<=Q<=50000)组操作,操作分为两种: 1.在x,y,z处添加一颗星星 2.询问以(x1,y1,z1)与(x2,y2,z2)为左上和右下顶点的矩形之间 ...

随机推荐

  1. CountDownLatch实现多线程并发请求

    package com.test; import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Dat ...

  2. grep使用集合

    一.grep使用 (一).选项 -a 不要忽略二进制数据. -A<显示列数> 除了显示符合范本样式的那一行之外,并显示该行之后的内容. -b 在显示符合范本样式的那一行之外,并显示该行之前 ...

  3. MRCPv2在电信智能语音识别业务中的应用

    1. MRCPv2协议简介 媒体资源控制协议(Media Resource Control Protocol, MRCP)是一种基于TCP/IP的通讯协议,用于客户端向媒体资源服务器请求提供各种媒体资 ...

  4. spark shuffle写操作之SortShuffleWriter

    提出问题 1. spark shuffle的预聚合操作是如何做的,其中底层的数据结构是什么?在数据写入到内存中有预聚合,在读溢出文件合并到最终的文件时是否也有预聚合操作? 2. shuffle数据的排 ...

  5. 【原创】TextCNN原理详解(一)

    ​ 最近一直在研究textCNN算法,准备写一个系列,每周更新一篇,大致包括以下内容: TextCNN基本原理和优劣势 TextCNN代码详解(附Github链接) TextCNN模型实践迭代经验总结 ...

  6. Of efficiency and methodology

    There are only too many articles and books which pertains to the discussion of efficiency and method ...

  7. jq css3实现跑马灯+大转盘

    前端效果, <!DOCTYPE HTML><html><head> <meta http-equiv="Content-Type" con ...

  8. 进程间通信与ipcs使用7例

    进程间通信(IPC, inter-process communication)实现进程间消息的传递,对于用户地址空间相互独立的两个进程而言,实现通信可以通过以下方式: 由内核层面分配内存,两进程共享该 ...

  9. POI通用导出Excel数据(包括样式设计)

    前言 前一段时间我写过通用的导入Excel,前几天也写了导出pdf格式的,还有我之前搞得导出Word,我在之前的博客也都介绍了导出和导入是一个道理,无非是一个获取一个是赋值.昨天有一位同仁看了我的Ex ...

  10. PHP 数组转字符串后仍保留数组格式

    写此方法的目的是,我想把一个PHP数组配置文件读进程序,添加些配置,然后在写入文件: var_export 方法会把原来的配置打乱(比如数组序号我没有加,他自动给我加上 0,1,2,3...),而且格 ...