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$ 一个虫子去吃最近的食物,如果有两个食物一样近,不转变方向的去吃 ...
随机推荐
- Redis与Scrapy
Redis与Scrapy Redis与Scrapy Redis is an open source, BSD licensed, advanced key-value cache and store. ...
- Toast添加动画
WindowManger wm =(WindowManger)context.getSystemService(Context.WINDOW_SERVICE); View view = Toast.m ...
- POJ 1631 Bridging signals & 2533 Longest Ordered Subsequence
两个都是最长上升子序列,所以就放一起了 1631 因为长度为40000,所以要用O(nlogn)的算法,其实就是另用一个数组c来存储当前最长子序列每一位的最小值,然后二分查找当前值在其中的位置:如果当 ...
- C#实现在winfrom程序中下载文件
//下载文件//downlaodUrl 系统路径如:http://xxx.xxx.xxx/UpFile/kaoqin.doc//fileName 自定义文件名字加后缀(如:考勤.doc)//fileP ...
- 检测android的网络链接状态
http://www.oschina.net/question/100267_61129?sort=default&p=1#tags_nav http://www.cnblogs.com/to ...
- 站在巨人的肩膀上,C++开源库大全
程序员要站在巨人的肩膀上,C++拥有丰富的开源库,这里包括:标准库.Web应用框架.人工智能.数据库.图片处理.机器学习.日志.代码分析等. 标准库 C++ Standard Library:是一系列 ...
- Unix/Linux环境C编程入门教程(30) 字符串操作那些事儿
函数介绍 rindex(查找字符串中最后一个出现的指定字符) 相关函数 index,memchr,strchr,strrchr 表头文件 #include<string.h> 定义函数 c ...
- UVA11988 Broken KeyBoard
链表的思想很简单,要做到活用也不难.一般我是这样做得,从实际问题出发,先高度的概括符不符合链表的特点.能不能用链表简单解决.接着,就是编码.链表编码要理清细节性思路,最好是简单的画下图,正如改题的链表 ...
- #include <boost/array.hpp>
Boost的array,元素可以是std::string #include <iostream> #include <string> #include <boost/ar ...
- EF框架+Lamada表达式(联合多表lamada表达式的用法)
有俩张表对应的EF框架的类Reviews和Commodity_Review,新建一个新的类,字段是联合俩张表后自己需要展示的字段ReviewsShow IQueryable<ReviewsSho ...