Luogu P3810 【模板】三维偏序(陌上花开)(CDQ分治)
题目
以三维偏序为例来讲一下CDQ分治。
CDQ的本质就是把一个序列分成两段,计算左边对右边的贡献,然后分治。
不过一般都是先分治到底再从下往上算,这样可以先归并再算。
比如这道题,我们先按第一维排序,然后分治完下一层之后边归并排序边算贡献。
具体大概是这样:
比如我们已经把下面的全部算完了,那么传上来的左边和有边一定满足:
1、左边的第一维都比右边的第一维小。
2、左边和右边在第二维上都是升序的。
那么我们归并排序,遇到左边的就加入数据结构修改贡献,遇到右边的就计算贡献。
同时我们能够保证传上去的是在第二维上是升序的。
在这一题的话,因为我们满足左边的第一维都比右边的小,两边的第二维都是升序,所以我们在归并的过程中只要对每个右边的计算前面的左边的第三维比它小的个数。这个可以通过离散化+去重+BIT维护桶解决。
跟整体二分一样,最后的清零要用撤销而不是memset,否则复杂度bomb。
#include<bits/stdc++.h>
using namespace std;
namespace IO
{
char ibuf[(1<<21)+1],obuf[(1<<21)+1],st[15],*iS,*iT,*oS=obuf,*oT=obuf+(1<<21);
char Get(){return (iS==iT? (iT=(iS=ibuf)+fread(ibuf,1,(1<<21)+1,stdin),(iS==iT? EOF:*iS++)):*iS++);}
void Flush(){fwrite(obuf,1,oS-obuf,stdout),oS=obuf;}
void Put(char x){*oS++=x;if(oS==oT)Flush();}
int read(){int x=0,c=Get();while(!isdigit(c))c=Get();while(isdigit(c))x=x*10+c-48,c=Get();return x;}
void write(int x){int top=0;if(!x)Put('0');while(x)st[++top]=(x%10)+48,x/=10;while(top)Put(st[top--]);Put('\n');}
}
using namespace IO;
const int N=100007,M=N<<1;
int k,p[N],q[N],a[N],b[N],c[N],t[M],v[N],cnt[N],ans[N];
int cmp(int x,int y){return a[x]<a[y]||(a[x]==a[y]&&(b[x]<b[y]||(b[x]==b[y]&&c[x]<c[y])));}
void modify(int i,int v){for(;i<=k;i+=i&-i)t[i]+=v;}
int query(int i){int sum=0;for(;i;i-=i&-i)sum+=t[i];return sum;}
void cdq(int *p,int n)
{
if(n==1) return;
int m=n>>1,i,j,k,x,y;
for(cdq(p,m),cdq(p+m,n-m),memcpy(q,p,n<<2),k=i=0,j=m;i<m&&j<n;++k)
{
x=q[i],y=q[j];
if(b[x]<=b[y]) modify(c[p[k]=x],v[x]),++i; else cnt[y]+=query(c[p[k]=y]),++j;
}
for(;j<n;++j) cnt[q[j]]+=query(c[q[j]]);
for(memcpy(p+k,q+i,(m-i)<<2),--i;~i;--i) modify(c[q[i]],-v[q[i]]);
}
int main()
{
int n=read(),i,j,x,y;
for(k=read(),i=0;i<n;++i) p[i]=i,a[i]=read(),b[i]=read(),c[i]=read();
for(sort(p,p+n,cmp),i=1,j=0;i<n;++i)
{
x=p[i],y=p[j],++v[y];
if(a[x]^a[y]||b[x]^b[y]||c[x]^c[y]) p[++j]=x;
}
++v[p[j++]],cdq(p,j);
for(i=0;i<j;++i) ans[cnt[p[i]]+v[p[i]]-1]+=v[p[i]];
for(i=0;i<n;++i) write(ans[i]);
return Flush(),0;
}
Luogu P3810 【模板】三维偏序(陌上花开)(CDQ分治)的更多相关文章
- BZOJ3262: 陌上花开(三维偏序,CDQ分治)
Description 有n朵花,每朵花有三个属性:花形(s).颜色(c).气味(m),用三个整数表示. 现在要对每朵花评级,一朵花的级别是它拥有的美丽能超过的花的数量. 定义一朵花A比另一朵花B要美 ...
- HDU 5618 Jam's problem again(三维偏序,CDQ分治,树状数组,线段树)
Jam's problem again Time Limit: 5000/2500 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Othe ...
- hdu5618 (三维偏序,cdq分治)
给定空间中的n个点,问每个点有多少个点小于等于自己. 先来分析简单的二维的情况,那么只要将x坐标排序,那么这样的问题就可以划分为两个子问题,,这样的分治有一个特点,即前一个子问题的解决是独立的,而后一 ...
- P3810 陌上花开 CDQ分治
陌上花开 CDQ分治 传送门:https://www.luogu.org/problemnew/show/P3810 题意: \[ 有n 个元素,第 i 个元素有 a_i. b_i. c_i 三个属性 ...
- 洛谷P3810 陌上花开 CDQ分治(三维偏序)
好,这是一道三维偏序的模板题 当然没那么简单..... 首先谴责洛谷一下:可怜的陌上花开的题面被无情的消灭了: 这么好听的名字#(滑稽) 那么我们看了题面后就发现:这就是一个三维偏序.只不过ans不加 ...
- BZOJ 3262: 陌上花开 [CDQ分治 三维偏序]
Description 有n朵花,每朵花有三个属性:花形(s).颜色(c).气味(m),又三个整数表示.现要对每朵花评级,一朵花的级别是它拥有的美丽能超过的花的数量.定义一朵花A比另一朵花B要美丽,当 ...
- 【BZOJ-3262】陌上花开 CDQ分治(3维偏序)
3262: 陌上花开 Time Limit: 20 Sec Memory Limit: 256 MBSubmit: 1439 Solved: 648[Submit][Status][Discuss ...
- N维偏序:cdq分治
cdq(陈丹琦)分治,是一种类似二分的算法.基本思想同分治: 递归,把大问题划分成若干个结构相同的子问题,直到(L==R): 处理左区间[L,mid]对右区间[mid+1,R]的影响: 合并. 它可以 ...
- bzoj3262陌上花开 cdq分治
3262: 陌上花开 Time Limit: 20 Sec Memory Limit: 256 MBSubmit: 2794 Solved: 1250[Submit][Status][Discus ...
- bzoj3262: 陌上花开(cdq分治+树状数组)
3262: 陌上花开 题目:传送门 题解: %%%cdq分治 很强大的一个暴力...感觉比分块高级多了 这道题目就是一个十分经典的三维偏序的例题: 一维直接暴力排序x 二维用csq维护y 三维用树状数 ...
随机推荐
- C语言的预编译,程序员必须懂的知识!【预编译指令】【预编译过程】
由“源代码”到“可执行文件”的过程包括四个步骤:预编译.编译.汇编.链接.所以,首先就应该清楚的首要问题就是:预编译只是对程序的文本起作用,换句话说就是,预编译阶段仅仅对源代码的单词进行变换,而不是对 ...
- Java_GUI小游戏--FlappyBird 橡树鸟
本文讲解的是一款来自独立游戏开发者Dong Nguyen所开发的游戏FlappyBird,也叫橡树鸟 四个类代码: package Gary; import java.awt.*; import ja ...
- Android学习_广播接收器
一.广播 1. 标准广播和有序广播 标准广播:异步,发出消息,所有接收器同时接收.但无法被截断 有序广播:同步,同一时刻只有一个广播接收器接收.可截断消息. 2. 广播注册 代码中注册(动态注册).A ...
- Python中很少见的用法
print(*range(10)) # 自动解开可迭代的对象
- 一本学习HTTP很好的书《图解HTTP》
网上电子版的一堆(*^__^*) 嘻嘻……
- react 路由
react 提供了实现路由的方式,不过需要我们下载插件 react-router-dom 当我们下载好了插件,然后我们可以通过 import {} from 'react-router-dom' 来引 ...
- 删除github上的一个repository
在学github之初,我们免不了会建立一些简单的repository,那么,如何删掉它们呢? 第一步,打开所要删除的repository,比如:meilin.github.io 第二步,点击setti ...
- .net中错误日志的写入
18 public static void SaveError(Exception ex,HttpContext hc,HttpRequest hr)19 {20 string temp ; ...
- C++函数传值问题
在做题出现个神奇的事情,C++的传值跟其他OOP语言不一样.首先做个测试,看看下面输出结果是什么? void F(int a,int b,int c){ cout<<a<<b& ...
- linux 基础 VIM 编辑器