这应该是一道CDQ分治的入门题目

我们知道,二维度的偏序问题直接通过,树状数组就可以实现了,但是三维如何实现呢?

我记得以前了解过一个小故事,应该就是分治的。

一个皇帝,想给部下分配任务,但是部下太多,他也无从下手于是他这个任务分给宰相,宰相也不怎么清楚,于是他又分给他的手下,这么一直分啊分啊,分到每一个人头顶上的时候

每个人知道自己要干什么,于是他把它的信息交给他的上级,上级有了这些数据后,他处理了交给他的上级。。。这么一直交啊。。。国王最后成功的分配这些任务。

CDQ分治也是一样,在这里,首先我们需要对X坐标进行排序,排序成功后,我们对区间进行分割,每次对区间进行二分,分成 [L - MID] [MID+1 - R]

我们分到底部的时候,实际上就是左右相等,于是只需要计算单个元素的效果,然后回到上一级,由于我们计算了两个区间的值,所以只需要计算 [MID+1 R] 对[L ,MID] 结果的影响即可

放到这道题,我们把X排序,然后枚举区间,对于【L,MID】对【MID+1,R】区间的贡献来说,应该如何计算呢?首先我们知道左边的区间的x肯定是小于右区间,我们其实已经可以不用

考虑X的影响了,所以我们对这连个区间对Y进行排序,那么我们要的三维偏序应该是,右边每一个值y,对应左边比右边的y小的值,我们把它的Z加入树状数组,像维护二维偏序一样维护

那么最后每个点贡献我们就可以得到,但是维护了每一段后,我们应该把树状数组进行清空,不然下次计算就有问题了。

注意要去重!!!

#include<iostream>
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<vector>
#define LL long long
using namespace std;
const int maxx = 3e6+;
struct node{
int x,y,z,cnt,ans;
}flower[maxx];
int sum[maxx];
int num[maxx];
int n,k,tot;
int lowbit(int x){
return x&(-x);
}
void add(int x,int w){
for (int i=x;i<=k;i+=lowbit(i)){
sum[i]+=w;
}
}
int query(int x){
int ans=;
for (int i=x;i;i-=lowbit(i)){
ans+=sum[i];
}
return ans;
}
bool cmpy(node a,node b){
if(a.y==b.y){
if (a.z==b.z){
return a.x<b.x;
}
return a.z<b.z;
}
return a.y<b.y;
}
bool cmpx(node a,node b){
if(a.x==b.x){
if (a.y==b.y){
return a.z<b.z;
}
return a.y<b.y;
}
return a.x<b.x;
}
void cdq(int l,int r){
if(l==r){
flower[l].ans+=flower[l].cnt-;
return ;
}
int mid=(l+r)>>;
cdq(l,mid);
cdq(mid+,r);
sort(flower+l,flower+mid+,cmpy);
sort(flower+mid+,flower+r+,cmpy);
int j=l;
for (int i=mid+;i<=r;i++){
while(j<=mid && flower[j].y<=flower[i].y){
add(flower[j].z,flower[j].cnt);
j++;
}
flower[i].ans+=query(flower[i].z);
}
for (int i=l;i<j;i++){
add(flower[i].z,-flower[i].cnt);
}
}
int main(){
scanf("%d%d",&n,&k);
for (int i=;i<=n;i++){
scanf("%d%d%d",&flower[i].x,&flower[i].y,&flower[i].z);
flower[i].ans=;
}
sort(flower+,flower++n,cmpx);
int tot=;
for (int i=;i<=n;i++){
if(i!= && flower[i].x==flower[i-].x && flower[i].y==flower[i-].y && flower[i].z==flower[i-].z){
flower[tot].cnt++;
}else {
tot++;
flower[tot]=flower[i];
flower[tot].cnt=;
}
}
// for (int i=1;i<=tot;i++){
// cout<<flower[i].x<<" "<<flower[i].y<<" "<<flower[i].z<<" "<<flower[i].cnt<<" "<<flower[i].ans<<endl;
// }
cdq(,tot);
for (int i=;i<=tot;i++){
num[flower[i].ans]+=flower[i].cnt;
}
for (int i=;i<=n;i++){
printf("%d\n",num[i]);
}
return ;
}
/*
1 2 2 1 1
2 2 1 1 1
2 2 3 2 1
2 3 3 0 1
3 2 1 2 1
3 2 2 0 1
3 3 3 0 1
*/

CDQ分治 三维偏序的更多相关文章

  1. BZOJ 3262: 陌上花开 [CDQ分治 三维偏序]

    Description 有n朵花,每朵花有三个属性:花形(s).颜色(c).气味(m),又三个整数表示.现要对每朵花评级,一朵花的级别是它拥有的美丽能超过的花的数量.定义一朵花A比另一朵花B要美丽,当 ...

  2. 洛谷P3810 陌上花开 CDQ分治(三维偏序)

    好,这是一道三维偏序的模板题 当然没那么简单..... 首先谴责洛谷一下:可怜的陌上花开的题面被无情的消灭了: 这么好听的名字#(滑稽) 那么我们看了题面后就发现:这就是一个三维偏序.只不过ans不加 ...

  3. 【算法】CDQ分治 -- 三维偏序 & 动态逆序对

    初次接触CDQ分治,感觉真的挺厉害的.整体思路即分而治之,再用之前处理出来的答案统计之后的答案. 大概流程是(对于区间 l ~ r): 1.处理 l ~mid, mid + 1 ~ r 的答案: 2. ...

  4. NEUOJ 1702:撩妹全靠魅力值(CDQ分治三维偏序)

    http://acm.neu.edu.cn/hustoj/problem.php?id=1702 思路:三维偏序模板题,用CDQ分治+树状数组或者树套树.对于三元组(x,y,z),先对x进行排序,然后 ...

  5. BZOJ 2244: [SDOI2011]拦截导弹 (CDQ分治 三维偏序 DP)

    题意 略- 分析 就是求最长不上升子序列,坐标取一下反就是求最长不下降子序列,比较大小是二维(h,v)(h,v)(h,v)的比较.我们不看概率,先看第一问怎么求最长不降子序列.设f[i]f[i]f[i ...

  6. cdq分治·三维偏序问题

    转载自FlashHu大佬的博客CDQ分治总结(CDQ,树状数组,归并排序),在讲述部分有部分删改,用了自己的代码 CDQ分治的思想 CDQ分治是基于时间的离线分治算法.这一类分治有一个重要的思想——用 ...

  7. BZOJ.1935.[SHOI2007]Tree园丁的烦恼(CDQ分治 三维偏序)

    题目链接 矩形查询可以拆成四个点的前缀和查询(树套树显然 但是空间不够) 每个操作表示为(t,x,y),t默认有序,对x分治,y用树状数组维护 初始赋值需要靠修改操作实现. //119964kb 43 ...

  8. BZOJ.3262.陌上花开([模板]CDQ分治 三维偏序)

    题目链接 BZOJ3262 洛谷P3810 /* 5904kb 872ms 对于相邻x,y,z相同的元素要进行去重,并记录次数算入贡献(它们之间产生的答案是一样的,但不去重会..) */ #inclu ...

  9. BZOJ - 1935 / 1176 cdq分治 三维偏序

    题意:给定n*m的网格,且给出n个(x,y)表示该网格已被占有,q次询问(x1,y1)到(x2,y2)的网格中有多少个被占有,n,m范围1e7,q范围5e5 cdq按x轴排序,树状数组维护y轴 #in ...

随机推荐

  1. Uva1252 Twenty Questions

    Twenty Questions https://odzkskevi.qnssl.com/15b7eb4cd1f75f63cee3945b0b845e4f?v=1508411736 [题解] dp[S ...

  2. 在虚拟机Ubuntu14.04中设置静态ip后无法上网的问题的解决

    背景:用着实验室代理服务器上网. 原因:网关和DNS没有设置正确 网关和DNS参照 真机cmd在命令窗口使用ipconfig  /all命令查看   虚拟机: sudo gedit /etc/netw ...

  3. SAE J2534介绍

    概要 J2534是一种针对与射频相关的ECU进行闪存编程的概念,而不用考虑ECU使用的通信协议.其目的是所有类型的ECU都应当只需一个工具(硬件设备),通常被称为通过式设备.J2534设备和ECU之间 ...

  4. 【Codeforces Round #430 (Div. 2) B】Gleb And Pizza

    [链接]点击打开链接 [题意] 在这里写题意 [题解] 根据圆心到原点的距离这个东西判断一下圆在不在那个环里面就好 [错的次数] 0 [反思] 在这了写反思 [代码] #include <cst ...

  5. webstorm/phpstorm破解版教程网址

    http://idea.lanyus.com/ http://www.php.cn/tool/phpstorm/408348.html 如果正版到期了,重新安装不能再次免费试用的话,之后我就用老版的w ...

  6. mysql各个引擎区别

    1.如果你有一个 MyISAM 数据表包含着 FULLTEXT 或 SPATIAL 索引,你将不能把它转换为使用 另一种引擎,因为只有 MyISAM 支持这两种索引. 2. 如果你有一个数据表包含着一 ...

  7. Leetcode908.Smallest Range I最小差值1

    给定一个整数数组 A,对于每个整数 A[i],我们可以选择任意 x 满足 -K <= x <= K,并将 x 加到 A[i] 中. 在此过程之后,我们得到一些数组 B. 返回 B 的最大值 ...

  8. JavaScript--函数中this的几种指向

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  9. laravel之文件上传

    laravel框架中的文件上传我们应该如何实现此功能呢? 之前也是没有使用过laravel的文件上传功能,后来在网上找到一些教程,五花八门.让我看起来有点头疼. 有时候找到测试浪费好长时间最后还是出不 ...

  10. Directx11教程(9) 增加一个TimerClass类

    原文:Directx11教程(9) 增加一个TimerClass类      在上篇教程代码的基础上,我们增加一个TimerClass类,这个类的功能很简单,就是可以计算相邻2帧的时间差.利用这个时间 ...