【总结】偏序/数点
这是一篇关于偏序/数点的总结
偏序是个什么东西?
我不知道准确的定义
但大概是以下例子表达出来的意思
一维偏序:一堆一维点,对于每个 \(i\) 求满足 \(point[j].x<=point[i].x\) 的 \(j\) 的个数
二维偏序:一堆二维点,对于每个 \(i\) 求满足 \(point[j].x<=point[i].x\ \&\&\ point[j].y<=point[i].y\) 的 \(j\) 的个数
三维偏序:一堆三维点,对于每个 \(i\) 求满足 \(point[j].x<=point[i].x\ \&\&\ point[j].y<=point[i].y\ \&\&\ point[j].z<=point[i].z\) 的 \(j\) 的个数
……
大概知道了吧
什么时候用?
- 裸题就不用说了
- 然后,有些时候代码中出现了类似偏序的式子(就是上面一堆小于等于的式子)的计数,就可以把这个计数的任务交给偏序去做
- 发挥人类智慧的题目
做法
这里给出三维以内的偏序大概做法,但因为这个东西还是比较偏的,所以不太详细,也都只给出了一种做法(其实每一种都有很多做法,最好是能找到最好理解的最适合自己的方法)
- 一维偏序
这。。。BIT直接维护(类似于求逆序对。这不就是个求顺序对?) - 二维偏序
我们先按照第一关键字排序,这样排序后我们就保证了后面的点的第一关键字一定大于等于前面的点的第一关键字,然后第二维也用BIT维护就行了 - 三维偏序
CDQ分治+BIT
对于CDQ分治,我无能为力,不知道的百度吧(以前学姐发明的东东,我之前居然没听说过。。)
先按照第一关键字排序,然后CDQ分治。对于每一层,我们已经保证了第一关键字的大小顺序,那么我们就把前半部分(为什么是前半部分?我们在分治啊!)的标记成能够修改BIT,也就是能对后半部分加贡献的,然后后面一半标记成只能接受贡献的。然后再把这一块按照第二关键字排序,这样我们既有之前的标记保证了第一关键字的顺序,又有之后的排序保证了第二关键字的排序,所以对于第三关键字,又可以用BIT了
还有四维,五维……无所谓,CDQ分治可以嵌套
最后有一道三维偏序的模板题,【刷题】BZOJ 3262 陌上花开