hdu5618(cdq分治求三维偏序)

题意:给n(n<=100000)个点,坐标为(xi,yi,zi)(1<=xi,yi,zi<=100000),定义一个点A比一个点B小,当且仅当xA<=xB,yA<=yB,zA<=zB。求对于每个点,有多少个点比它小。

分析:

   首先肯定按照x递增顺序排个序

   接下来就是每次往平面插入一个点,求这个点左下方已经有多少个点,这可以用二维树状数组来搞,但是很明显会爆空间,不可以接受(当然树套树也是不可以的)

   可以考虑对第二维cdq分治

   对于一个区间[l,r],先递归区间[l,mid],再整体考虑[l,mid]对[mid+1,r]的贡献,再递归[mid+1,r]

   重要考虑[l,mid]对[mid+1,r]的贡献

   因为[l,mid]中的x都小于等于[mid+1,r]中的x,那么可以不考虑x了,直接考虑第二维y

   将两个区间分别按照y从小到大排序

   弄两个指针分别从左端开始移动,对于[l,mid]中的y<=[mid+1,r]中的y,那么就把对应的z丢到树状数组中

   那么对于[mid+1,r]中的每个位置,在相应的时间就可以计算[l,mid]中的点对此位置的贡献

   时间复杂度O(nlog^2n)

   一维排序,二维cdq,三维数据结构,考虑左区间的修改对于右区间查询的影响

  

时间: 2024-12-29 06:58:28

hdu5618(cdq分治求三维偏序)的相关文章

SPOJ:Another Longest Increasing Subsequence Problem(CDQ分治求三维偏序)

Given a sequence of N pairs of integers, find the length of the longest increasing subsequence of it. An increasing sequence A1..An is a sequence such that for every i < j, Ai < Aj. A subsequence of a sequence is a sequence that appears in the same

HDU5618 &amp; CDQ分治

Description: 三维数点 Solution: 第一道cdq分治...感觉还是很显然的虽然题目不能再傻逼了... Code: /*================================= # Created time: 2016-04-20 10:00 # Filename: hdu5618.cpp # Description: =================================*/ #define me AcrossTheSky&HalfSummer11 #i

UvaLive 6667 Longest Chain (分治求三维LIS)

题目大意: 题目给出了定义的小于号,然后求出一个LIS... 思路分析: 这道题目的是一个严格递增的,和 Hdu 4742 类似.只不过Hdu的这道题是一个不递减的序列. 简单说一下Hdu 4742的做法. 首先我们可以想到的是一维的LIS,那么简单就是n. 然后二维的LIS,就是先排序一维,然后用求第二维的LIS. 现在问题扩展到三维.依然排序一维. 假设我们排序的是z. 然后记下排序后的id.现在已知,id小的z就小. 然后开始分治,类似线段树的递归.对于一个区间,我们将这个区间的所有元素取

CDQ分治求前缀和

1 #include<bits/stdc++.h> 2 using namespace std; 3 const int N=200005; 4 int n,a_tot,q_tot,ans[N]; 5 char s[10]; 6 struct query 7 { 8 int id,v,op; 9 bool operator < (const query &rhs)const 10 { 11 if(id==rhs.id) return op<rhs.op; 12 return

BZOJ 3295:[Cqoi2011]动态逆序对(三维偏序 CDQ分治+树状数组)

http://www.lydsy.com/JudgeOnline/problem.php?id=3295 题意:简单明了. 思路:终于好像有点明白CDQ分治处理三维偏序了.把删除操作看作是插入操作,那么可以按照插入的时间顺序看作是一维x,插入的数在原本序列的下标是一维y,插入的数本身是一维z.那么问题可以转化成每插入一个数(xx,yy,zz),求有多少个数(x,y,z)使得 x < xx,y < yy,z > zz .一开始先对 x 进行排序,然后进行CDQ分治.这样可以干掉一维,保证随

P3157 [CQOI2011]动态逆序对 (CDQ解决三维偏序问题)

P3157 [CQOI2011]动态逆序对 题目描述 对于序列A,它的逆序对数定义为满足i<j,且Ai>Aj的数对(i,j)的个数.给1到n的一个排列,按照某种顺序依次删除m个元素,你的任务是在每次删除一个元素之前统计整个序列的逆序对数. 输入格式 输入第一行包含两个整数n和m,即初始元素的个数和删除的元素个数.以下n行每行包含一个1到n之间的正整数,即初始排列.以下m行每行一个正整数,依次为每次删除的元素. 输出格式 输出包含m行,依次为删除每个元素之前,逆序对的个数. 输入输出样例 输入

【模板】CDQ分治

其实我的CDQ分治写的和shi一样 参悟了好长时间才大概知道CDQ分治该怎么搞,按照网上的资料半抄半写弄了道BZOJ3262陌上花开,但是评测不了,只把样例给过了,所以仍然不知道这个板子是不是对的. 以下叙述都是博主从其他BLOG里东拼西凑的: CDQ分治用来解决一类可离线的问题,通常是有一堆奇奇怪怪的修改和询问,然后拿高级数据结构做来很恶心的题目. CDQ分治的基本套路: 1.把待处理区间[l,r]分为[l,mid]和[mid+1,r]两个区间,递归处理下去. 2.处理[l,mid]区间的修改

CDQ 分治算法模板

CDQ分治 1.三维偏序问题:三维偏序(陌上花开) #include<bits/stdc++.h> #define RG register #define IL inline #define _ 200005 using namespace std; IL int gi(){ RG int data = 0 , m = 1; RG char ch = 0; while(ch != '-' && (ch<'0'||ch>'9'))ch = getchar(); if(

SPOJ LIS2 Another Longest Increasing Subsequence Problem 三维偏序最长链 CDQ分治

Another Longest Increasing Subsequence Problem Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://acm.hust.edu.cn/vjudge/problem/visitOriginUrl.action?id=19929 Description Given a sequence of N pairs of integers, find the length of the longest incre