最近才学了cdq,所以用cdq写的代码(这道题也是cdq的模板题)

这道题是个三维偏序问题,先对第一维排序,然后去掉重复的,然后cdq分治即可。

为什么要去掉重复的呢?因为相同的元素互相之间都能贡献,而cdq过程中只能左边贡献右边的,所以要去重。

  1. 1 #include<bits/stdc++.h>
  2. 2 using namespace std;
  3. 3 const int N=200005;
  4. 4 struct node{
  5. 5 int a,b,c,cnt,ans;
  6. 6 }s1[N],s2[N];
  7. 7 int n,k,mx,m,top,su[N];
  8. 8 int c[N];//树状数组
  9. 9
  10. 10 bool cmp1(node x,node y){//按a排序
  11. 11 if(x.a==y.a){
  12. 12 if(x.b==y.b) return x.c<y.c;
  13. 13 else return x.b<y.b;
  14. 14 }
  15. 15 else return x.a<y.a;
  16. 16 }
  17. 17
  18. 18 bool cmp2(node x,node y){//cdq分治过程中对b排序
  19. 19 if(x.b==y.b) return x.c<y.c;
  20. 20 else return x.b<y.b;
  21. 21 }
  22. 22
  23. 23 int lowbit(int x){
  24. 24 return x&(-x);
  25. 25 }
  26. 26
  27. 27 void add(int x,int k){
  28. 28 while(x<=mx){
  29. 29 c[x]+=k;
  30. 30 x+=lowbit(x);
  31. 31 }
  32. 32 }
  33. 33
  34. 34 int query(int x){
  35. 35 int sum=0;
  36. 36 while(x){
  37. 37 sum+=c[x];
  38. 38 x-=lowbit(x);
  39. 39 }
  40. 40 return sum;
  41. 41 }
  42. 42
  43. 43 void cdq(int l,int r){//cdq
  44. 44 if(l==r) return ;
  45. 45 int mid=(l+r)>>1;
  46. 46 cdq(l,mid);cdq(mid+1,r);
  47. 47 sort(s2+l,s2+1+mid,cmp2);
  48. 48 sort(s2+mid+1,s2+r+1,cmp2);
  49. 49 int i,j=l;
  50. 50 for(int i=mid+1;i<=r;i++){//双指针计算结果
  51. 51 while(s2[i].b>=s2[j].b&&j<=mid){
  52. 52 add(s2[j].c,s2[j].cnt);
  53. 53 j++;
  54. 54 }
  55. 55 s2[i].ans+=query(s2[i].c);//计算ans
  56. 56 }
  57. 57 for(int i=l;i<j;i++){//清空数组
  58. 58 add(s2[i].c,-s2[i].cnt);
  59. 59 }
  60. 60 }
  61. 61
  62. 62 int main()
  63. 63 {
  64. 64 scanf("%d%d",&n,&k);
  65. 65 mx=k;
  66. 66 for(int i=1;i<=n;i++){
  67. 67 int a,b,c;
  68. 68 scanf("%d%d%d",&a,&b,&c);
  69. 69 s1[i].a=a;s1[i].b=b;s1[i].c=c;
  70. 70 }
  71. 71 sort(s1+1,s1+1+n,cmp1);
  72. 72 for(int i=1;i<=n;i++){//去掉重复的
  73. 73 top++;
  74. 74 if(s1[i].a!=s1[i+1].a||s1[i].b!=s1[i+1].b||s1[i].c!=s1[i+1].c){
  75. 75 m++;
  76. 76 s2[m].a=s1[i].a;s2[m].b=s1[i].b;s2[m].c=s1[i].c;
  77. 77 s2[m].cnt=top;
  78. 78 top=0;
  79. 79 }
  80. 80 }
  81. 81 cdq(1,m);
  82. 82 for(int i=1;i<=m;i++) su[s2[i].ans+s2[i].cnt-1]+=s2[i].cnt;
  83. 83 for(int i=0;i<n;i++)
  84. 84 cout<<su[i]<<endl;
  85. 85 return 0;
  86. 86 }

洛谷P3810 陌上花开 (cdq)的更多相关文章

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

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

  2. 洛谷P3810 陌上花开(CDQ分治)

    洛谷P3810 陌上花开 传送门 题解: CDQ分治模板题. 一维排序,二维归并,三维树状数组. 核心思想是分治,即计算左边区间对右边区间的影响. 代码如下: #include <bits/st ...

  3. BZOJ3262/洛谷P3810 陌上花开 分治 三维偏序 树状数组

    原文链接http://www.cnblogs.com/zhouzhendong/p/8672131.html 题目传送门 - BZOJ3262 题目传送门 - 洛谷P3810 题意 有$n$个元素,第 ...

  4. P3810 陌上花开 CDQ分治

    陌上花开 CDQ分治 传送门:https://www.luogu.org/problemnew/show/P3810 题意: \[ 有n 个元素,第 i 个元素有 a_i. b_i. c_i 三个属性 ...

  5. 洛谷 P3810 【模板】三维偏序(陌上花开) (cdq分治模板)

    在solve(L,R)中,需要先分治solve两个子区间,再计算左边区间修改对右边区间询问的贡献. 注意,计算额外的贡献时,两子区间各自内部的顺序变得不再重要(不管怎么样左边区间的都发生在右边之前), ...

  6. [bzoj] 3263 陌上花开 洛谷 P3810 三维偏序|| CDQ分治 && CDQ分治讲解

    原题 定义一个点比另一个点大为当且仅当这个点的三个值分别大于等于另一个点的三个值.每比一个点大就为加一等级,求每个等级的点的数量. 显然的三维偏序问题,CDQ的板子题. CDQ分治: CDQ分治是一种 ...

  7. 【洛谷P3810】陌上花开

    题目大意:给定一个三维空间点的坐标,求对于任意一个点三维均小于等于这个点的点个数. 题解:学会了简单的 cdq 分治. 首先,先将第一维从小到大排序,再用类似归并排序的操作对第二维进行排序,在第二维合 ...

  8. [洛谷P3810]【模板】三维偏序(陌上花开)

    题目大意:有$n$个元素,第$i$个元素有三个属性$a_i,b_i,c_i$,设$f(i)=\sum\limits_{i\not = j}[a_j\leqslant a_i,b_j\leqslant ...

  9. 洛谷P4390 Mokia CDQ分治

    喜闻乐见的CDQ分治被我搞的又WA又T..... 大致思路是这样的:把询问用二维前缀和的思想拆成4个子询问.然后施CDQ大法即可. 我却灵光一闪:树状数组是可以求区间和的,那么我们只拆成两个子询问不就 ...

随机推荐

  1. java------注释、关键字、字面量

    注释(对代码的一种解释说明) 单行注释   // 多行注释   /*   */ 文档注释 /** */ 注释使用细节: 注释内容不参与编译和运行,所以只在java文件中存在 不管是单行注释还是多行注释 ...

  2. raspberrypi系统在加入k8s作为node节点时遇到的问题

    新买的树莓派4b到货后就迫不及待的烧录上raspberrypi系统,将新派加入我的k8s集群,期间遇到了点小挫折,好歹也一个一个解决了: 一.kubelet版本不对导致无法加入k8s集群 在执行kub ...

  3. 体验Lambda的更优写法和Lambda标准格式

    体验Lambda的更优写法 借助Java8的全新语法,上述Runnable接口的匿名内部类写法可以通过更简单的Lambda表达式达到等效: public class Lambda02 { public ...

  4. 题解 P4999 【烦人的数学作业】

    数位 dp. 设 \(dp_{q,i}\)(\(i\in\{0,1,2,3,4,5,6,7,8,9\}\))为 \(1\sim q\) 中 \(i\) 出现的次数,\(1\sim q\) 的数字和显然 ...

  5. C# 从补码中获取有符号数的实际数值

    C# 从补码中获取有符号数的实际数值 原理 计算机存储数据时,默认是存储数据的补码.有符号的数粗存在符号位(最高位). 这里就会提到原码.反码.补码的概念. 原码:用符号位和数值表示带符号数,正数的符 ...

  6. 在微信小程序中,如何获取 for 循环的 index

    微信小程序中,for 循环的 index(索引值)可以用wx:for-index="index"来获取. <view class="item" wx:fo ...

  7. LeetCode 593. 有效的正方形(向量做法)

    题目 题目链接:593. 有效的正方形 题意:给出二维平面上四个点的坐标,判断这四个点是否能构成一个正方形,四个点的输入顺序不做任何保证. 思路 通过向量运算可以很轻松地解决这道题.任取一点向其他三点 ...

  8. [CTSC2007]数据备份Backup (贪心)

    题面 Description 你在一家 IT 公司为大型写字楼或办公楼(offices)的计算机数据做备份.然而数据备份的工作是枯燥乏味的,因此你想设计一个系统让不同的办公楼彼此之间互相备份,而你则坐 ...

  9. OpenJudge1.5.17

    20:球弹跳高度的计算 总时间限制: 1000ms 内存限制: 65536kB 描述 一球从某一高度落下(整数,单位米),每次落地后反跳回原来高度的一半,再落下. 编程计算气球在第10次落地时,共经过 ...

  10. Linux常用基础命令一

    一.目录操作 进入路径 cd [目录地址] 切换回主目录 cd 返回上一个路径 cd - 打印当前路径 pwd 列出目录下文件 ls ---查看只包含非隐藏文件 ls -a -----查看目录下所有文 ...