题意:Q次操作,三维空间内 每个星星对应一个坐标,查询以(x1,y1,z1) (x2,y2,z2)为左下顶点 、右上顶点的立方体内的星星的个数。

注意Q的范围为50000,显然离散化之后用三维BIT会MLE。 我们可以用一次CDQ把三维变成二维,变成二维之后就有很多做法了,树套树,不会树套树的话还可以继续CDQ由二维变成一维,,变成一维了就好做了,,最基本的数据结构题目了。。

不得不说、CDQ真的很神奇。

下面做法就是CDQ套CDQ套树状数组。

 #include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn = ;
inline int lowbit (int x)
{
return x & -x;
}
int c[maxn*],MAX;
void add(int x,int d)
{
while (x <= MAX)
{
c[x] += d;
x += lowbit(x);
}
}
int sum(int x)
{
int ans = ;
while (x)
{
ans += c[x];
x -= lowbit (x);
}
return ans;
}
struct Point
{
int x,y,z;
int kind,idx,delt;
Point() {}
Point(int _x,int _y,int _z,int _delt,int _kind,int _idx):
x(_x), y(_y), z(_z), delt(_delt), kind(_kind), idx(_idx) {} } star[maxn << ],star3[maxn << ];
int ans[maxn<<];
bool cmp1(const Point &p1,const Point &p2)
{
return p1.x < p2.x || ((p1.x == p2.x) && (p1.idx < p2.idx) );
}
bool cmp2(const Point &p1,const Point &p2)
{
return p1.y < p2.y || ((p1.y == p2.y) && (p1.idx < p2.idx) );
}
void CDQ2(int l,int r)
{
if (l >= r)
return;
int mid = (l + r) >> ;
CDQ2(l,mid);
CDQ2(mid+,r);
int j = l;
for (int i = mid + ; i <= r; i++)
{
if (star3[i].kind == )
{
for ( ; j <= mid && (star3[j].y <= star3[i].y); j++)
{
if (star3[j].kind == )
add(star3[j].z,star3[j].delt);
}
ans[star3[i].idx] += sum(star3[i].z) * star3[i].delt;
}
}
for (int i = l; i < j; i++)
{
if (star3[i].kind == )
add(star3[i].z,-star3[i].delt);
}
inplace_merge(star3+l,star3+mid+,star3+r+,cmp2);
}
void CDQ1(int l,int r)
{
if (l == r)
return;
int mid = (l + r) >> ;
CDQ1(l, mid);
CDQ1(mid+, r);
int tot = ;
for (int j = l; j <= mid ; j++)
if (star[j].kind == )
star3[tot++] = star[j];
for (int i = mid + ; i <= r; i++)
{
if (star[i].kind == )
star3[tot++] = star[i];
}
sort(star3+,star3+tot,cmp1);
CDQ2(,tot-);
}
int vec[maxn << ],idx;
void hash_(int tot)
{
sort(vec,vec+idx);
idx = unique(vec,vec+idx) - vec;
MAX = idx + ;
for (int i = ; i <= tot; i++)
star[i].z = lower_bound(vec,vec+idx,star[i].z) - vec + ;
}
int main(void)
{
#ifndef ONLINE_JUDGE
freopen("in.txt","r",stdin);
#endif // ONLINE_JUDGE
int T,Q;
scanf ("%d",&T);
while (T--)
{
scanf ("%d",&Q);
int tot = ;
int totq = ;
idx = ;
memset(c,,sizeof (c));
memset(ans,,sizeof(ans));
for (int i = ; i <= Q; i++)
{
int op,x1,y1,z1,x2,y2,z2;
scanf ("%d",&op);
if (op == )
{
scanf ("%d%d%d",&x1,&y1,&z1);
star[tot] = Point(x1,y1,z1,,,totq);
vec[idx++] = z1;
ans[totq] = -;
tot++;
totq++;
}
if (op == )
{
scanf ("%d%d%d%d%d%d",&x1,&y1,&z1,&x2,&y2,&z2);
star[tot] = Point(x1-, y1-, z1-, -, , totq), vec[idx++] = z1-, tot++;
star[tot] = Point(x2, y1-, z1-, , , totq), vec[idx++] = z1-, tot++;
star[tot] = Point(x2 , y2 , z1-, -, , totq), vec[idx++] = z1-, tot++;
star[tot] = Point(x1-, y2, z1-, , , totq), vec[idx++] = z1-, tot++;
star[tot] = Point(x1-, y2, z2 , -, , totq), vec[idx++] = z2 , tot++;
star[tot] = Point(x2 , y2, z2 , , , totq), vec[idx++] = z2 , tot++;
star[tot] = Point(x2 , y1-, z2 , -, , totq), vec[idx++] = z2 , tot++;
star[tot] = Point(x1-, y1-, z2 , , , totq), vec[idx++] = z2 , tot++;
totq++;
}
}
hash_(tot);
CDQ1(,tot-);
for (int i = ; i < totq; i++)
if (~ans[i])
printf("%d\n",ans[i]);
}
return ;
}

HDU5126---stars (CDQ套CDQ套 树状数组)的更多相关文章

  1. HDU 5618 Jam's problem again (cdq分治+BIT 或 树状数组套Treap)

    题意:给n个点,求每一个点的满足 x y z 都小于等于它的其他点的个数. 析:三维的,第一维直接排序就好按下标来,第二维按值来,第三维用数状数组维即可. 代码如下: cdq 分治: #pragma ...

  2. HDU 4247 Pinball Game 3D(cdq 分治+树状数组+动态规划)

    Pinball Game 3D Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) ...

  3. HDU 5618 Jam's problem again(三维偏序,CDQ分治,树状数组,线段树)

    Jam's problem again Time Limit: 5000/2500 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Othe ...

  4. BZOJ2683: 简单题(cdq分治 树状数组)

    Time Limit: 50 Sec  Memory Limit: 128 MBSubmit: 2142  Solved: 874[Submit][Status][Discuss] Descripti ...

  5. 【二维偏序】【树状数组】【权值分块】【分块】poj2352 Stars

    经典问题:二维偏序.给定平面中的n个点,求每个点左下方的点的个数. 因为 所有点已经以y为第一关键字,x为第二关键字排好序,所以我们按读入顺序处理,仅仅需要计算x坐标小于<=某个点的点有多少个就 ...

  6. 【BZOJ1146】网络管理(主席树,树状数组)

    [BZOJ1146]网络管理(主席树,树状数组) 题面 BZOJ权限题,洛谷题面 题解 树上带修改主席树 貌似和\(Count\ On\ A\ Tree\)那题很相似呀 只需要套上一个树状数组来维护修 ...

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

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

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

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

  9. [Bzoj3262]陌上花开(CDQ分治&&树状数组||树套树)

    题目链接 题目就是赤裸裸的三维偏序,所以用CDQ+树状数组可以比较轻松的解决,但是还是树套树好想QAQ CDQ+树状数组 #include<bits/stdc++.h> using nam ...

随机推荐

  1. CVE-2014-0196(马拉松赛跑bug)

    /* * CVE-2014-0196: Linux kernel <= v3.15-rc4: raw mode PTY local echo race * condition * * Sligh ...

  2. MySQL定时备份之使用Linux下的crontab定时备份实例

    这篇文章主要介绍了使用Linux下的crontab进行MySQL定时备份的例子,需要的朋友可以参考下   复制代码代码如下: ##################################### ...

  3. c#中WebBrowser控件的使用方法

    首先先来简单介绍一下webbrowser控件,这个控件是可以实现在form窗体中添加网页内容的.如图,我在form中加入了百度api,(百度地图api调用博客里有讲) 使用这个控件其实很简单 (1)第 ...

  4. [转] gdb 查看vector, list, map 内容

    转:http://blog.chinaunix.net/uid-13982689-id-34282.html先下载gdb_stl_utils.tar.gz, extract it, and run m ...

  5. .NET简单的语句

    获取当前时间的代码: Response.Write(DateTime.Now); 第一次加载页面的语句: if (!IsPostBack) { Response.Write("这是第一次加载 ...

  6. session过期后自动跳转到登陆页

    项目需要做一个自动登出的功能,查询了网上的资料,一开始准备用session监听做,按照下面方式配置监听器 1.在项目的web.xml文件中添加如下代码: <!--添加Session监听器--&g ...

  7. Target runtime Apache Tomcat v6.0 is not defined. phyy Unknown Faceted Project Problem

    Description Resource Path Location TypeTarget runtime Apache Tomcat v6.0 is not defined. phyy Unknow ...

  8. sql 删除多项

    delete from 表名 where 字段 in(值,值,值.......)

  9. hdu 5105

    题意: y=|a*x^3+b*x^2+c*x+d|    求y的最大值? 题目是bc上的,之前写的时候,没考虑0的情况(太笨了).... 水题吧.... AC代码: #include <iost ...

  10. C++线性序列容器<vector>简单总结

    C++线性序列容器<vector>简单总结 vector是一个长度可变的数组,使用的时候无须声明上限,随着元素的增加,Vector的长度会自动增加:Vector类提供额外的方法来增加.删除 ...