HDU - 5126: stars (求立方体内点数 CDQ套CDQ)
题意:现在给定空空的三维平面,有加点操作和询问立方体点数。
思路:考虑CDQ套CDQ。复杂度是O(NlogN*logN*logN),可以过此题。
具体的,这是一个四维偏序问题,4维分别是(times,x,y,z);我们知道cdq可以求出t<=T,x=X,y<=Y,在套一层就可以z<=Z了。那么一个立方体,我们拆为8个点来容斥。
然后现在的问题就是,求出(0,0,0)到(x,y,z)的点数。 第一维T已经默认排序了,我们先对X分治。 把所有问题分成两块,并且把左边这块标记o=-1,右边的标记o=1,然后塞到正常的CDQ里面,对y进行分治,对z进行统计。 此时一个z要插入树状数组,需要格外满足o=-1;而询问需要格外满足o=1;
对于CDQ:先对一维分治,两个小区间搞完后后,归并排序就可以了,这样避开了sort。 这里还可以为了方便用inplace_merge,但是比手写慢一些。
#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=a;i<=b;i++)
using namespace std;
const int maxn=;
struct in{
int x,y,z,id,opt,o; //编号,正负,第一维是否在左
}s[maxn],q[maxn],fcy[maxn];
bool cmp1(in w,in v) { return w.x<v.x;}
bool cmp2(in w,in v) { return w.y<v.y;}
int b[maxn],sz,tot,cnt,ans[maxn],sum[maxn];
void add(int x,int val)
{
for(int i=x;i<=sz;i+=(-i)&i) sum[i]+=val;
}
int query(int x)
{
int res=;
for(int i=x;i;i-=(-i)&i) res+=sum[i];
return res;
}
void cdq2(int L,int R)
{
if(L>=R) return ;
int Mid=(L+R)>>,i=L,j=Mid+,now;
cdq2(L,Mid); cdq2(Mid+,R);
for(;j<=R;j++){
for(;i<=Mid&&q[i].y<=q[j].y;i++){
if(q[i].o==-&&q[i].opt==) add(q[i].z,);
}
if(q[j].o==&&q[j].id) ans[q[j].id]+=q[j].opt*query(q[j].z);
}
while((--i)>=L) if(q[i].o==-&&!q[i].id) add(q[i].z,-); /*i=L,j=Mid+1,now=L; 手写归并,下面cdq1同理。
while(j<=R&&i<=Mid){
if(q[i].y<=q[j].y) fcy[now++]=q[i++];
else fcy[now++]=q[j++];
}
while(i<=Mid) fcy[now++]=q[i++];
while(j<=R) fcy[now++]=q[j++];
rep(i,L,R) q[i]=fcy[i];*/
inplace_merge(q+L,q+Mid+,q+R+,cmp2); //归并排序
}
void cdq1(int L,int R)
{
if(L>=R) return ;
int Mid=(L+R)>>,i=L,j=Mid+,now=L;
cdq1(L,Mid); cdq1(Mid+,R);
//sort(s+L,s+Mid+1,cmp1); sort(s+Mid+1,s+R+1,cmp1);
tot=;
while(j<=R&&i<=Mid){
if(s[i].x<=s[j].x){
fcy[now++]=s[i];
q[++tot]=s[i++],q[tot].o=-;
if(s[i-].id) tot--;
}
else {
fcy[now++]=s[j];
q[++tot]=s[j++],q[tot].o=;
if(!s[j-].id) tot--;
}
}
while(i<=Mid) {
fcy[now++]=s[i];
q[++tot]=s[i++],q[tot].o=-;
if(s[i-].id) tot--;
}
while(j<=R) {
fcy[now++]=s[j];
q[++tot]=s[j++],q[tot].o=;
if(!s[j-].id) tot--;
}
rep(i,L,R) s[i]=fcy[i];
//inplace_merge(s+L,s+Mid+1,s+R+1,cmp1);
cdq2(,tot);
}
void solve()
{
int N,Q=,opt,x1,y1,z1,x2,y2,z2;
sz=; tot=;
scanf("%d",&N);
rep(i,,N){
scanf("%d",&opt);
if(opt&){
scanf("%d%d%d",&x1,&y1,&z1);
b[++sz]=z1;
s[++tot]=in{x1,y1,z1,,,};
}
else {
scanf("%d%d%d%d%d%d",&x1,&y1,&z1,&x2,&y2,&z2);
b[++sz]=z1; b[++sz]=z2; b[++sz]=z1-; ans[++Q]=;
s[++tot]=in{x2,y2,z2,Q,,};
s[++tot]=in{x1-,y1-,z1-,Q,-,};
s[++tot]=in{x1-,y2,z2,Q,-,};
s[++tot]=in{x1-,y1-,z2,Q,,};
s[++tot]=in{x1-,y2,z1-,Q,,};
s[++tot]=in{x2,y1-,z2,Q,-,};
s[++tot]=in{x2,y2,z1-,Q,-,};
s[++tot]=in{x2,y1-,z1-,Q,,};
}
}
sort(b+,b+sz+);
cnt=unique(b+,b+sz+)-(b+);
rep(i,,tot) s[i].z=lower_bound(b+,b+sz+,s[i].z)-b;
cdq1(,tot);
rep(i,,Q) printf("%d\n",ans[i]);
}
int main()
{
int T; scanf("%d",&T);
while(T--) solve();
return ;
}
HDU - 5126: stars (求立方体内点数 CDQ套CDQ)的更多相关文章
- HDU5126---stars (CDQ套CDQ套 树状数组)
题意:Q次操作,三维空间内 每个星星对应一个坐标,查询以(x1,y1,z1) (x2,y2,z2)为左下顶点 .右上顶点的立方体内的星星的个数. 注意Q的范围为50000,显然离散化之后用三维BIT会 ...
- cogs2479 偏序(CDQ套CDQ)
题目链接 思路 四维偏序 \(CDQ\)套\(CDQ\),第一维默认有序.第二维用第一个\(CDQ\)变成有序的.并且对每个点标记上第一维属于左边还是右边.第二个\(CDQ\)处理第三维,注意两个\( ...
- [HZOI 2016] 偏序(CDQ套CDQ)
传送门 思路: 就是cdq套cdq的模板题 #include <bits/stdc++.h> using namespace std; typedef long long ll; cons ...
- hdu 5126 stars (四维偏序,离线,CDQ套CDQ套树状数组)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5126 思路:支持离线,那么我们可以用两次CDQ分治使四维降为二维,降成二维后排个序用树状数组维护下就好 ...
- HDU - 5126 stars (CDQ分治)
题目链接 题目大意:一共有Q(1<=Q<=50000)组操作,操作分为两种: 1.在x,y,z处添加一颗星星 2.询问以(x1,y1,z1)与(x2,y2,z2)为左上和右下顶点的矩形之间 ...
- HDU 5126 stars 4维偏序, CDQ套CDQ
题目传送门 题意:在一个星空中,按着时间会出现一些点,现在john想知道,在某个时间内有多少个星星是的坐标是满足条件的.(x1<=x<=x2, y1 <= y <= y2, z ...
- hdu 5126 stars cdq分治套cdq分治+树状数组
题目链接 给n个操作, 第一种是在x, y, z这个点+1. 第二种询问(x1, y1, z1). (x2, y2, z2)之间的总值. 用一次cdq分治可以将三维变两维, 两次的话就变成一维了, 然 ...
- HDU 5126 stars (四维偏序+树状数组)
题目大意:略 题目传送门 四维偏序板子题 把插入操作和询问操作抽象成$(x,y,z,t)$这样的四元组 询问操作拆分成八个询问容斥 此外$x,y,z$可能很大,需要离散 直接处理四维偏序很困难,考虑降 ...
- 【教程】CDQ套CDQ——四维偏序问题
前言 上一篇文章已经介绍了简单的CDQ分治,包括经典的二维偏序和三维偏序问题,还有带修改和查询的二维/三维偏序问题.本文讲介绍多重CDQ分治的嵌套,即多维偏序问题. 四维偏序问题 给定N( ...
随机推荐
- Apollo:微服务架构下的配置管理
问题背景 在实际工作中,我们的开发环境,测试环境,生产环境对应的 Mysql 数据库,Redis 这些信息都不一样,每个环境都有对应的一套配置,在 Spring Boot 中我们通常会编写多个配置文件 ...
- NOI 2010 海拔(最小割转最短路)
题意 https://www.lydsy.com/JudgeOnline/problem.php?id=2007 思路 首先可以发现一个结论,每个位置的海拔只有能是 \(0\) 和 \(1\) ,然后 ...
- I/O多路复用-EPOLL探索
什么是I/O多路复用 I/O多路复用就是通过一种机制,可以监视多个描述符,一旦某个IO能够读写,通知程序进行相应的读写操作. I/O多路复用的场合 1.当客户处理多个描述字时(通常是交互式输入和网络套 ...
- java核心技术(第十版卷一)笔记(纯干货!)
这是我读过的第三本关于java基础的书.第一本<<java从入门到精通>>这本书让我灵识初开.第二本<<java敏捷开发>>这本书则是有一次被一位师傅批 ...
- go-gin-api 路由中间件 - Jaeger 链路追踪
概述 首先同步下项目概况: 上篇文章分享了,路由中间件 - Jaeger 链路追踪(理论篇). 这篇文章咱们分享:路由中间件 - Jaeger 链路追踪(实战篇). 说实话,这篇文章确实让大家久等了, ...
- Mysql系列(十二)—— 索引下推优化
索引条件下推(ICP)是对MySQL使用索引从表中检索行的情况的优化.如果没有ICP,存储引擎会遍历索引以查找基表中的行,并将它们返回给MySQL服务器,该服务器会评估WHERE行的条件.启用ICP后 ...
- WPF 精修篇 WPF嵌入Winfrom控件
原文:WPF 精修篇 WPF嵌入Winfrom控件 先增加DLL 支持 使用 WindowsFormsHost 来加载Forms的控件 引用命名空间 xmlns:forms="clr-na ...
- .NetCore使用NLog写入数据库总结
考虑到项目后期添加日志的需求,抽个闲暇时间学习一下使用NLog插件将日志信息写入到数据库中,完整项目见下面: 遇到的问题: 使用NLog写到SQLServer里面的中文显示问号? 解决方法:调整数据库 ...
- 如何写出优雅的 Golang 代码
原文: https://draveness.me/golang-101.html Go 语言是一门简单.易学的编程语言,对于有编程背景的工程师来说,学习 Go 语言并写出能够运行的代码并不是一件困难的 ...
- Java I/O系统学习系列二:输入和输出
编程语言的I/O类库中常使用流这个抽象概念,它代表任何有能力产出数据的数据源对象或者是有能力接收数据的接收端对象.“流”屏蔽了实际的I/O设备中处理数据的细节. 在这个系列的第一篇文章:<< ...