HDU5126---stars (CDQ套CDQ套 树状数组)
题意: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套 树状数组)的更多相关文章
- HDU 5618 Jam's problem again (cdq分治+BIT 或 树状数组套Treap)
题意:给n个点,求每一个点的满足 x y z 都小于等于它的其他点的个数. 析:三维的,第一维直接排序就好按下标来,第二维按值来,第三维用数状数组维即可. 代码如下: cdq 分治: #pragma ...
- HDU 4247 Pinball Game 3D(cdq 分治+树状数组+动态规划)
Pinball Game 3D Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) ...
- 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 ...
- BZOJ2683: 简单题(cdq分治 树状数组)
Time Limit: 50 Sec Memory Limit: 128 MBSubmit: 2142 Solved: 874[Submit][Status][Discuss] Descripti ...
- 【二维偏序】【树状数组】【权值分块】【分块】poj2352 Stars
经典问题:二维偏序.给定平面中的n个点,求每个点左下方的点的个数. 因为 所有点已经以y为第一关键字,x为第二关键字排好序,所以我们按读入顺序处理,仅仅需要计算x坐标小于<=某个点的点有多少个就 ...
- 【BZOJ1146】网络管理(主席树,树状数组)
[BZOJ1146]网络管理(主席树,树状数组) 题面 BZOJ权限题,洛谷题面 题解 树上带修改主席树 貌似和\(Count\ On\ A\ Tree\)那题很相似呀 只需要套上一个树状数组来维护修 ...
- hdu 5126 stars cdq分治套cdq分治+树状数组
题目链接 给n个操作, 第一种是在x, y, z这个点+1. 第二种询问(x1, y1, z1). (x2, y2, z2)之间的总值. 用一次cdq分治可以将三维变两维, 两次的话就变成一维了, 然 ...
- hdu 5126 stars (四维偏序,离线,CDQ套CDQ套树状数组)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5126 思路:支持离线,那么我们可以用两次CDQ分治使四维降为二维,降成二维后排个序用树状数组维护下就好 ...
- [Bzoj3262]陌上花开(CDQ分治&&树状数组||树套树)
题目链接 题目就是赤裸裸的三维偏序,所以用CDQ+树状数组可以比较轻松的解决,但是还是树套树好想QAQ CDQ+树状数组 #include<bits/stdc++.h> using nam ...
随机推荐
- 二分-hdu-4768-Flyer
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4768 题目意思: 有n个A.B.C,每个Ai,Bi,Ci,对于每个P=Ai+k*Ci(P<=B ...
- 百度——LBS.云 v2.0——创建自己的地理云数据
随着云技术和地理信息(GIS)技术的发展,今年终于进入了.地理分享的新纪元.百度提供了LBS的云存储.真是个不错的功能.下面让我们来看看如何使用吧. 1.注册百度开发者账号(此处略去88个字) 2.创 ...
- js上拉加载、下拉刷新的插件
之前在网上找那种下拉刷新,上拉加载的插件,有一款IScroll,但是用起来太麻烦,于是就自己写了款,但依赖于jquery.js,bug肯定有,希望评论提出. js: /* 简洁的下拉刷新,上拉加载插件 ...
- 补间动画 Interpolator 简介 示例
简介 补间动画的原理: 每次绘制视图时View所在的[ViewGroup]中的drawChild函数获取该View的Animation的值,然后调用canvas.concat (transformTo ...
- 在Github上面搭建Hexo博客(一):部署到Github
什么是Hexo Hexo是一个基于Node.js的静态博客程序,可以方便的生成静态网页托管在Github和Heroku上.并且有很多人为其制作了很多优秀的主题(theme),你可以根据自己的喜好进行设 ...
- hdu 2201
题意: 一共有n个人,m表示第m个人,然后问你第i个人不做到m号位置的概率,最后相乘.... 水题(注意下格式输出) AC代码: #include <iostream> using nam ...
- 一个打砖块的小游戏1.0 KILL THE BLOCKS !
/******************************************** * 程序名称:MR.DUAN 的打砖块(KILL THE BLOCKS !) * 作 者:WindAutum ...
- XFire构建服务端Service的两种方式
1.原声构建: 2.集成spring构建 http://blog.csdn.net/carefree31441/article/details/4000436XFire构建服务端Service的两种方 ...
- Visual Studio使用技巧记录
1.关闭调试,iis express仍显示在托盘中: 工具 ---> 选项 ---> 调试 ---> 编辑并继续,取消选择“编辑并继续”的选择框 2.关闭浏览器一直请求: 在调试旁边 ...
- Ajax--JavaScript实现
Ajax:一种不用刷新整个页面便可与服务器通讯的办法 Ajax实现的步骤: 1.创建XMLHttpRequest对象 2.服务器向浏览器响应请求(注册监听) 3.浏览器与服务器建立连接 4.浏览器向服 ...