题目

以三维偏序为例来讲一下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分治)的更多相关文章

  1. BZOJ3262: 陌上花开(三维偏序,CDQ分治)

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

  2. 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 ...

  3. hdu5618 (三维偏序,cdq分治)

    给定空间中的n个点,问每个点有多少个点小于等于自己. 先来分析简单的二维的情况,那么只要将x坐标排序,那么这样的问题就可以划分为两个子问题,,这样的分治有一个特点,即前一个子问题的解决是独立的,而后一 ...

  4. P3810 陌上花开 CDQ分治

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

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

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

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

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

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

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

  8. N维偏序:cdq分治

    cdq(陈丹琦)分治,是一种类似二分的算法.基本思想同分治: 递归,把大问题划分成若干个结构相同的子问题,直到(L==R): 处理左区间[L,mid]对右区间[mid+1,R]的影响: 合并. 它可以 ...

  9. bzoj3262陌上花开 cdq分治

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

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

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

随机推荐

  1. matplotlib(二):折线图

    import numpy as np import matplotlib.pyplot as plt import matplotlib.dates as mdates # 解决中文显示问题 plt. ...

  2. 十一、spring插件

    1.STS插件_ springsource-tool-suite插件各个历史版本 2.eclipse安装spring的插件 3.奇技淫巧:在spring官网上下载历史版本的spring插件,sprin ...

  3. Eclipse改变成炫酷黑色主题

    有一个款Eclipse插件EclipseColorTheme,其官网地址是http://eclipsecolorthemes.org/,可以直接使用大量内置的样式主题模板,如果还不能满足你自己的个性化 ...

  4. DB 分库分表(3):关于使用框架还是自主开发以及 sharding 实现层面的考量

    当团队对系统业务和数据库进行了细致的梳理,确定了切分方案后,接下来的问题就是如何去实现切分方案了,目前在sharding方面有不少的开源框架和产品可供参考,同时很多团队也会选择自主开发实现,而不管是选 ...

  5. SpringBoot的文件上传&下载

    前言:不多BB直接上代码 文件上传 pom依赖添加commons-io <!-- 上传/下载jar https://mvnrepository.com/artifact/commons-io/c ...

  6. redux 第二部分

    redux 的使用方法, 为什么使用 action.js 文件,进行优化代码将其分开,然后我们通过工厂函数的每次返回不同的对象,由于参数是固定的,每次返回的都是事件类型和事件数据,所以我们可以使用一个 ...

  7. 在sed中引入shell变量的四种方法

    1.eval sed ’s/$a/$b/’ filename2.sed "s/$a/$b/" filename3.sed ’s/’$a’/’$b’/’ filename 4.sed ...

  8. 让SpringBoot工程支持热部署

    下载地址:https://files.cnblogs.com/files/xiandedanteng/SpringBootWeb-1_20190928.rar 修改Java文件后,每次要重启才好用,修 ...

  9. LC 833. Find And Replace in String

    To some string S, we will perform some replacement operations that replace groups of letters with ne ...

  10. GitHub-Tech-DotNet:Cnblogs

    ylbtech-GitHub-Tech-DotNet:Cnblogs 1.返回顶部 · EnyimMemcachedCore Forked from enyim/EnyimMemcached A Me ...