陌上花开 CDQ分治

传送门:https://www.luogu.org/problemnew/show/P3810

题意:

\[有n 个元素,第 i 个元素有 a_i、 b_i、 c_i 三个属性,设 f(i) 表示满足 a_j\leq a_i 且 b_j \leq b_i且 c_j \leq c_i的 j 的数量。\\
对于 d \in [0, n],求 f(i) = d 的数量
\]

题解:

CDQ分治模板题,

我们将第一维在主函数排序后,cdq分治里面,每次将左半边和右半边按照y排序,因为一开始的x是已经排序过了的,所以分治将其分为左半边和右半边时,左半边的x还是小于右半边的x,因此维护右半边的位置i和左半边的位置j,如果y[j]<y[i]的话,我们就可以将z[j]丢进树状数组中,直到y[j]>=y[i]时,不满足偏序关系的时候,我们就可以直接树状数组查询小于z[i]的前半部分的j的个数,这样,这么多个数就满足三维的偏序关系。

1.x的偏序关系已经在主函数里面处理,所以分治分了后前一半的x小于后一半的x

2.y的偏序关系是两个指针对着扫了,一遍,将满足y[j]<y[i]的z[j]丢进了树状数组统计个数

3.z的偏序关系是从树状数组中查的小于z[i]的z[j]有多少个

一直这样分治下去,我们就可以得到最终的答案

这个题有一个坑点就是,当x,y,z都相同时,在分治的时候,本来它们相互之间都有贡献,可是cdq的过程中只有左边的能贡献右边的。这可怎么办呢?我们直接离散化后,给定一个权值,这样算贡献就不会算错了

代码:

  1. #include <set>
  2. #include <map>
  3. #include <cmath>
  4. #include <cstdio>
  5. #include <string>
  6. #include <vector>
  7. #include <cstring>
  8. #include <iostream>
  9. #include <algorithm>
  10. using namespace std;
  11. typedef long long LL;
  12. typedef pair<int, int> pii;
  13. typedef unsigned long long uLL;
  14. #define ls rt<<1
  15. #define rs rt<<1|1
  16. #define lson l,mid,rt<<1
  17. #define rson mid+1,r,rt<<1|1
  18. #define bug printf("*********\n")
  19. #define FIN freopen("input.txt","r",stdin);
  20. #define FON freopen("output.txt","w+",stdout);
  21. #define IO ios::sync_with_stdio(false),cin.tie(0)
  22. #define debug1(x) cout<<"["<<#x<<" "<<(x)<<"]\n"
  23. #define debug2(x,y) cout<<"["<<#x<<" "<<(x)<<" "<<#y<<" "<<(y)<<"]\n"
  24. #define debug3(x,y,z) cout<<"["<<#x<<" "<<(x)<<" "<<#y<<" "<<(y)<<" "<<#z<<" "<<z<<"]\n"
  25. const int maxn = 3e5 + 5;
  26. const int INF = 0x3f3f3f3f;
  27. struct node {
  28. int x, y, z;
  29. int cnt;
  30. int ans;
  31. } a[maxn];
  32. bool cmpx(node a, node b) {
  33. if(a.x == b.x && a.y == b.y) return a.z < b.z;
  34. if(a.x == b.x) return a.y < b.y;
  35. return a.x < b.x;
  36. }
  37. bool cmpy(node a, node b) {
  38. if(a.y == b.y && a.z == b.z) return a.x < b.x;
  39. if(a.y == b.y) return a.z < b.z;
  40. return a.y < b.y;
  41. }
  42. int lowbit(int x) {
  43. return x & (-x);
  44. }
  45. int bit[maxn];
  46. void add(int pos, int val) {
  47. while(pos < maxn) {
  48. bit[pos] += val;
  49. pos += lowbit(pos);
  50. }
  51. }
  52. int sum(int pos) {
  53. int res = 0;
  54. while(pos) {
  55. res += bit[pos];
  56. pos -= lowbit(pos);
  57. }
  58. return res;
  59. }
  60. int num[maxn];
  61. void CDQ(int l, int r) {
  62. if(l == r) {
  63. a[l].ans += a[l].cnt - 1;
  64. return;
  65. }
  66. int mid = (l + r) >> 1;
  67. CDQ(l, mid);
  68. CDQ(mid + 1, r);
  69. sort(a + l, a + mid + 1, cmpy);
  70. sort(a + mid + 1, a + r + 1, cmpy);
  71. int j = l;
  72. for(int i = mid + 1; i <= r; i++) {
  73. while(j <= mid && a[j].y <= a[i].y) {
  74. add(a[j].z, a[j].cnt);
  75. j++;
  76. }
  77. a[i].ans += sum(a[i].z);
  78. }
  79. for(int i = l; i < j; i++) {
  80. add(a[i].z, -a[i].cnt);
  81. }
  82. }
  83. int main() {
  84. #ifndef ONLINE_JUDGE
  85. FIN
  86. #endif
  87. int n, k;
  88. scanf("%d%d", &n, &k);
  89. for(int i = 1; i <= n; i++) {
  90. scanf("%d%d%d", &a[i].x, &a[i].y, &a[i].z);
  91. a[i].ans = 1;
  92. }
  93. sort(a + 1, a + n + 1, cmpx);
  94. int tot = 0;
  95. for(int i = 1; i <= n; ++i) {
  96. if(i != 1 && a[i].x == a[i - 1].x && a[i].y == a[i - 1].y && a[i].z == a[i - 1].z) a[tot].cnt++;
  97. else a[++tot] = a[i], a[tot].cnt = 1;
  98. }
  99. CDQ(1, tot);
  100. sort(a + 1, a + tot + 1, cmpx);
  101. for(int i = 1; i <= tot; i++) {
  102. num[a[i].ans] += a[i].cnt;
  103. }
  104. for(int i = 1; i <= n; i++) {
  105. printf("%d\n", num[i]);
  106. }
  107. return 0;
  108. }

P3810 陌上花开 CDQ分治的更多相关文章

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

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

  2. 【BZOJ-3262】陌上花开 CDQ分治(3维偏序)

    3262: 陌上花开 Time Limit: 20 Sec  Memory Limit: 256 MBSubmit: 1439  Solved: 648[Submit][Status][Discuss ...

  3. bzoj3262陌上花开 cdq分治

    3262: 陌上花开 Time Limit: 20 Sec  Memory Limit: 256 MBSubmit: 2794  Solved: 1250[Submit][Status][Discus ...

  4. 【CJOJ2433】陌上花开 CDQ分治

    [CJOJ2433]陌上花开 CDQ呲嘚秋分治 WA果然呲嘚秋分治跑得比树套树还快!!!(md理论复杂度不是一样的吗) 但树套树不知道比呲嘚秋高到哪里去辣装X用 Orz hzwer 第一维sort,第 ...

  5. 【BZOJ3262】陌上花开 cdq分治

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

  6. bzoj3262: 陌上花开(cdq分治+树状数组)

    3262: 陌上花开 题目:传送门 题解: %%%cdq分治 很强大的一个暴力...感觉比分块高级多了 这道题目就是一个十分经典的三维偏序的例题: 一维直接暴力排序x 二维用csq维护y 三维用树状数 ...

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

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

  8. bzoj 3262 陌上花开 - CDQ分治 - 树状数组

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

  9. 陌上花开——CDQ分治

    传送门 “CDQ分治”从来都没有听说过,写了这题才知道还有这么神奇的算法. (被逼无奈).w(゚Д゚)w 于是看了不少dalao的博客,对CDQ算法粗浅地了解了一点.(想要了解CDQ的概念,可以看下这 ...

随机推荐

  1. 【AtCoder Regular Contest 092】C.2D Plane 2N Points【匈牙利算法】

    C.2D Plane 2N Points 题意:给定N个红点二维坐标N个蓝点二维坐标,如果红点横纵坐标都比蓝点小,那么它们能够构成一组.问最多能构成多少组. 题解:把满足要求的红蓝点连线,然后就是匈牙 ...

  2. C++:for范围循环特点--自我理解

    for(declaration : expression)statement for(xx-type i : P)....其一:for范围类型循环在循环前,可能会对p所在的队列里,对每一个对象进行一次 ...

  3. Java排序需掌握算法 详解

    package com.sxt.review; /*内部排序:(在内存) * 插入排序-->希尔排序 * 冒泡排序-->快速排序 * 选择排序-->堆排序 * 归并排序 * 基数排序 ...

  4. python 文件读写编码

  5. Person Re-identification 系列论文笔记(四):Re-ID done right: towards good practices for person re-identification

    Re-ID done right: towards good practices for person re-identification Almazan J, Gajic B, Murray N, ...

  6. 应用node-webkit(NWJS)把BS架构的网址封装成桌面应用

    一.目的 给WEB应用的用户提供一款同一的浏览器,访问固定网址,封装一些常用插件(如flash插件等) 二.步骤 1.下载node-webkit,官方网址https://nwjs.io/ 2.解压下载 ...

  7. C++大体概况 标签: c++总结 2015-01-31 20:41 792人阅读 评论(15) 收藏

    今年又一次报名了二级的C++考试,现在再来把C++总结一下,也不能算是总结,大体提炼了一下需要注意的地方,考试之前打算把这些东西好好看一看,今年一定要过啊! 前两天才知道,unix是用C语言编写的,这 ...

  8. lattice planner 规划详解

    大家好,我是来自百度智能驾驶事业群的许珂诚.今天很高兴能给大家分享Apollo 3.0新发布的Lattice规划算法. Lattice算法隶属于规划模块.规划模块以预测模块.routing模块.高精地 ...

  9. 求eclipse中的java build path 详解

    我也找了一下资料,但未找到相关的正式说明,我只能凭经验告诉你. 1,Source是指资源的路径.例如在没有包含res之前,资源是放在与src同级位置,或者通过/res/*.*来操作的.2,Projec ...

  10. C#中的?操作符

    一.1个?的用法 1. 表示可空数据类型,如 int? bool? 2. 跟在对象后,如该对象为null,则不会触发空值异常,且整个表达式返回null,如: string kk = "123 ...