题目链接

给n个操作, 第一种是在x, y, z这个点+1. 第二种询问(x1, y1, z1). (x2, y2, z2)之间的总值。

用一次cdq分治可以将三维变两维, 两次的话就变成一维了, 然后最后一维用树状数组维护。 对于每个询问, 相当于将它拆成8个点。

注意第二次cdq分治的时候l可能小于r。 所以这里的return条件是l <= r而不是l == r。 找了好久...

#include <bits/stdc++.h>
using namespace std;
#define pb(x) push_back(x)
#define mem(a) memset(a, 0, sizeof(a))
vector <int> b;
const int maxn = 5e4+;
struct node
{
int x1, y1, z1, x2, y2, z2;
int sign, id;
node(){}
node(int x, int y, int z, int sign, int id):x1(x), y1(y), z1(z), sign(sign), id(id){}
}a[maxn], s[maxn*], ss[maxn*], c[maxn*];
bool cmpx(node a, node b)
{
if(a.x1 == b.x1)
return a.id < b.id;
return a.x1 < b.x1;
}
bool cmpy(node a, node b)
{
if(a.y1 == b.y1)
return a.id < b.id;
return a.y1 < b.y1;
}
int len, sum[maxn*], ans[maxn];
int lowbit(int x) {return x&(-x);}
void update(int x, int val) {
while(x <= len) {
sum[x] += val;
x += lowbit(x);
}
}
int query(int x, int ret = )
{
while(x) {
ret += sum[x];
x -= lowbit(x);
}
return ret;
}
void cdqy(int l, int r)
{
if(l >= r)
return ;
int m = l+r>>, cnt = ;
cdqy(l, m);
cdqy(m+, r);
for(int i = l; i <= m; i++) {
if(s[i].sign == ) {
ss[cnt++] = s[i];
}
}
for(int i = m+; i <= r; i++) {
if(s[i].sign != ) {
ss[cnt++] = s[i];
}
}
sort(ss, ss+cnt, cmpy);
for(int i = ; i < cnt; i++) {
if(ss[i].sign == ) {
update(ss[i].z1, );
} else if(ss[i].sign == ) {
ans[ss[i].id] += query(ss[i].z1);
} else {
ans[ss[i].id] -= query(ss[i].z1);
}
}
for(int i = ; i < cnt; i++) {
if(ss[i].sign == ) {
update(ss[i].z1, -);
}
}
}
void cdqx(int l, int r)
{
if(l == r)
return ;
int m = l+r>>, top = ;
cdqx(l, m);
cdqx(m+, r);
for(int i = l; i <= m; i++) {
if(c[i].sign == ) {
s[++top] = c[i];
}
}
for(int i = m+; i <= r; i++) {
if(c[i].sign != ) {
s[++top] = c[i];
}
}
sort(s+, s++top, cmpx);
cdqy(, top);
}
void solve(int n, int num = )
{
sort(b.begin(), b.end());
b.erase(unique(b.begin(), b.end()), b.end());
len = b.size();
for(int i = ; i <= n; i++) {
if(a[i].sign == ) {
c[++num] = a[i];
} else {
c[++num] = node(a[i].x2, a[i].y2, a[i].z2, , a[i].id);
c[++num] = node(a[i].x1-, a[i].y1-, a[i].z1-, , a[i].id);
c[++num] = node(a[i].x2, a[i].y2, a[i].z1-, , a[i].id);
c[++num] = node(a[i].x2, a[i].y1-, a[i].z2, , a[i].id);
c[++num] = node(a[i].x1-, a[i].y2, a[i].z2, , a[i].id);
c[++num] = node(a[i].x1-, a[i].y1-, a[i].z2, , a[i].id);
c[++num] = node(a[i].x1-, a[i].y2, a[i].z1-, , a[i].id);
c[++num] = node(a[i].x2, a[i].y1-, a[i].z1-, , a[i].id);
}
}
for(int i = ; i <= num; i++) {
c[i].z1 = lower_bound(b.begin(), b.end(), c[i].z1)-b.begin()+;
}
cdqx(, num);
}
int main()
{
int t, n;
cin>>t;
while(t--) {
cin>>n;
mem(sum);
mem(ans);
for(int i = ; i <= n; i++) {
scanf("%d%d%d%d", &a[i].sign, &a[i].x1, &a[i].y1, &a[i].z1);
if(a[i].sign == ) {
scanf("%d%d%d", &a[i].x2, &a[i].y2, &a[i].z2);
b.pb(a[i].z2);
b.pb(a[i].z1-);
} else {
b.pb(a[i].z1);
}
a[i].id = i;
}
solve(n);
for(int i = ; i <= n; i++) {
if(a[i].sign == ) {
printf("%d\n", ans[i]);
}
}
}
return ;
}

hdu 5126 stars cdq分治套cdq分治+树状数组的更多相关文章

  1. hdu 1556:Color the ball(第二类树状数组 —— 区间更新,点求和)

    Color the ball Time Limit: 9000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)To ...

  2. HDU 3887:Counting Offspring(DFS序+树状数组)

    http://acm.hdu.edu.cn/showproblem.php?pid=3887 题意:给出一个有根树,问对于每一个节点它的子树中有多少个节点的值是小于它的. 思路:这题和那道苹果树是一样 ...

  3. HDU 5654 xiaoxin and his watermelon candy 离线树状数组 区间不同数的个数

    xiaoxin and his watermelon candy 题目连接: http://acm.hdu.edu.cn/showproblem.php?pid=5654 Description Du ...

  4. HDU 5293 Annoying problem 树形dp dfs序 树状数组 lca

    Annoying problem 题目连接: http://acm.hdu.edu.cn/showproblem.php?pid=5293 Description Coco has a tree, w ...

  5. HDU 2227 Find the nondecreasing subsequences dp思想 + 树状数组

    http://acm.hdu.edu.cn/showproblem.php?pid=2227 用dp[i]表示以第i个数为结尾的nondecreasing串有多少个. 那么对于每个a[i] 要去找 & ...

  6. POJ 3321:Apple Tree + HDU 3887:Counting Offspring(DFS序+树状数组)

    http://poj.org/problem?id=3321 http://acm.hdu.edu.cn/showproblem.php?pid=3887 POJ 3321: 题意:给出一棵根节点为1 ...

  7. hdu 4715 Difference Between Primes(素数筛选+树状数组哈希剪枝)

    http://acm.hdu.edu.cn/showproblem.php?pid=4715 [code]: #include <iostream> #include <cstdio ...

  8. HDU 4605 Magic Ball Game (dfs+离线树状数组)

    题意:给你一颗有根树,它的孩子要么只有两个,要么没有,且每个点都有一个权值w. 接着给你一个权值为x的球,它从更节点开始向下掉,有三种情况 x=w[now]:停在此点 x<w[now]:当有孩子 ...

  9. HDU 4267 A Simple Problem with Integers(树状数组区间更新)

    A Simple Problem with Integers Time Limit: 5000/1500 MS (Java/Others)    Memory Limit: 32768/32768 K ...

  10. Holedox Eating HDU - 4302 2012多校C 二分查找+树状数组/线段树优化

    题意 一个长度$n<=1e5$的数轴,$m<=1e5$个操作 有两种一些操作 $0$  $x$ 在$x$放一个食物 $1$ 一个虫子去吃最近的食物,如果有两个食物一样近,不转变方向的去吃 ...

随机推荐

  1. Unique Binary Search Trees,Unique Binary Search Trees II

    Unique Binary Search Trees Total Accepted: 69271 Total Submissions: 191174 Difficulty: Medium Given  ...

  2. Q - 密码(第二季水)

    Description 网上流传一句话:"常在网上飘啊,哪能不挨刀啊-".其实要想能安安心心地上网其实也不难,学点安全知识就可以.         首先,我们就要设置一个安全的密码 ...

  3. Android url中文编码问题

    最近项目遇见一个很奇葩问题,关于URL问题,项目中加载图片,图片的URL含有中文,但是,我的手机可以加载,没问题,同事也都可以,但是测试手机却不可以,加载失败,找到问题,就是URL含有中文问题. 解决 ...

  4. Red and Black(水)

    Red and Black Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Tot ...

  5. To and Fro(字符串水题)

    To and Fro 点我 Problem Description Mo and Larry have devised a way of encrypting messages. They first ...

  6. android重要的对象

    Context----------------访问全局信息的api Activity Window Intent/Bundle ImageView----------onclick View----- ...

  7. git 拉取远程分之到本地

    git checkout -b newbranch_name --track origin/feature/newbranch_name 如果遇到类似: fatal: git checkout: up ...

  8. index seek与index scan

    原文地址:http://blog.csdn.net/pumaadamsjack/article/details/6597357 低效Index Scan(索引扫描):就全扫描索引(包括根页,中间页和叶 ...

  9. poj 1018 Communication System_贪心

    题意:给你n个厂,每个厂有m个产品,产品有B(带宽),P(价格),现在要你求最大的 B/P 明显是枚举,当P大于一定值,B/P为零,可以用这个剪枝 #include <iostream> ...

  10. 电脑中已有VS2005和VS2010安装.NET3.5失败的解决方案

    1.重启 MSI 安装服务: 运行-输入“CMD”命令,在弹出的对话框中输入命令: msiexec/unregserver ,回车,并再次输入 msiexec/regserver . 2.启用 Pri ...