hdu 5126 stars cdq分治套cdq分治+树状数组
给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分治+树状数组的更多相关文章
- hdu 1556:Color the ball(第二类树状数组 —— 区间更新,点求和)
Color the ball Time Limit: 9000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)To ...
- HDU 3887:Counting Offspring(DFS序+树状数组)
http://acm.hdu.edu.cn/showproblem.php?pid=3887 题意:给出一个有根树,问对于每一个节点它的子树中有多少个节点的值是小于它的. 思路:这题和那道苹果树是一样 ...
- HDU 5654 xiaoxin and his watermelon candy 离线树状数组 区间不同数的个数
xiaoxin and his watermelon candy 题目连接: http://acm.hdu.edu.cn/showproblem.php?pid=5654 Description Du ...
- HDU 5293 Annoying problem 树形dp dfs序 树状数组 lca
Annoying problem 题目连接: http://acm.hdu.edu.cn/showproblem.php?pid=5293 Description Coco has a tree, w ...
- HDU 2227 Find the nondecreasing subsequences dp思想 + 树状数组
http://acm.hdu.edu.cn/showproblem.php?pid=2227 用dp[i]表示以第i个数为结尾的nondecreasing串有多少个. 那么对于每个a[i] 要去找 & ...
- 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 ...
- hdu 4715 Difference Between Primes(素数筛选+树状数组哈希剪枝)
http://acm.hdu.edu.cn/showproblem.php?pid=4715 [code]: #include <iostream> #include <cstdio ...
- HDU 4605 Magic Ball Game (dfs+离线树状数组)
题意:给你一颗有根树,它的孩子要么只有两个,要么没有,且每个点都有一个权值w. 接着给你一个权值为x的球,它从更节点开始向下掉,有三种情况 x=w[now]:停在此点 x<w[now]:当有孩子 ...
- HDU 4267 A Simple Problem with Integers(树状数组区间更新)
A Simple Problem with Integers Time Limit: 5000/1500 MS (Java/Others) Memory Limit: 32768/32768 K ...
- Holedox Eating HDU - 4302 2012多校C 二分查找+树状数组/线段树优化
题意 一个长度$n<=1e5$的数轴,$m<=1e5$个操作 有两种一些操作 $0$ $x$ 在$x$放一个食物 $1$ 一个虫子去吃最近的食物,如果有两个食物一样近,不转变方向的去吃 ...
随机推荐
- JS delete 用法(删除对象属性及变量)
1,对象属性删除 function fun(){ this.name = 'mm'; } var obj = new fun(); console.log(obj.name);//mm delete ...
- AngularJs中关于ng-class的三种使用方式说明
在开发中我们通常会遇到一种需求:一个元素在不同的状态需要展现不同的样子. 而在这所谓的样子当然就是改变其css的属性,而实现能动态的改变其属性值,必然只能是更换其class属性 这里有三种方法: 第一 ...
- HTML5 canvas 在线画笔绘图工具(四)
HTML5画图命令 图形的绘制是由TDrawHandler与TCommand 协同工作完成. TDrawHandler需要完成以下工作 1.聚集类用于管理绘图的命令 TCommand 2.管理鼠标事件 ...
- 使用事件CreateEvent注意事项
HANDLECreateEvent( LPSECURITY_ATTRIBUTESlpEventAttributes,// 安全属性 BOOLbManualReset,// 复位方式 BOOLbInit ...
- 一个简化的printf函数
<C和指针>第7章第5道编程题: 实现一个简化的printf函数,它能够处理%d.%f.%s 和 %c 格式码,根据ANSI标准的原则,其他格式码的行为是未定义的.你可以假定已经存在函数 ...
- GDAL库——读取图像并提取基本信息
GDAL库是一个跨平台的栅格地理数据格式库,包括读取.写入.转换.处理各种栅格数据格式(有些特定的格式对一些操作如写入等不支持).它使用了一个单一的抽象数据模型就支持了大多数的栅格数据.这里有GDAL ...
- U盘读写速度测试
1.ATTO Disk Benchmark 测U盘读写速度 ATTO Disk Benchmark 是一款简单易用的磁盘传输速率检测软件,可以用来检测硬盘.U盘.存储卡及其它可移动磁盘的读取及写 ...
- 为什么在DllMain里不能调用LoadLibrary和FreeLibrary函数?
为什么在DllMain里不能调用LoadLibrary和FreeLibrary函数? MSDN里对这个问题的答案十分的晦涩.不过现在我们已经有了足够的知识来解答这个问题.考虑下面的情况: ...
- 杭电oj 3079 Vowel Counting
Tips:可以先将输入的字符串全部转化为小写字母,然后再将元音字母变为大写,时间复杂度O(n) #include<stdio.h> #include<string.h> #in ...
- ubuntu登陆后一闪回到登陆界面
ubuntu登陆后一闪回到登陆界面 最后发现居然是我的环境变量配置问题........ 解决方法: 先CTRL+ALT+F1 root进去, 查看nickleo用户为什么登录失败 ca ...