题目传送门


题目描述

有$n$朵花,每朵花有三个属性:花形$(s)$、颜色$(c)$、气味$(m)$,用三个整数表示。
现在要对每朵花评级,一朵花的级别是它拥有的美丽能超过的花的数量。
定义一朵花$A$比另一朵花$B$要美丽,当且仅$S_a\geqslant S_b,C_a\geqslant C_b,M_a\geqslant M_b$。
显然,两朵花可能有同样的属性。需要统计出评出每个等级的花的数量。


输入格式

第一行为$N,K$,分别表示花的数量和最大属性值。
以下$N$行,每行三个整数$s_i,c_i,m_i$,表示第$i$朵花的属性。


输出格式

包含$N$行,分别表示评级为$0...N-1$的每级花的数量。


样例

样例输入

10 3
3 3 3
2 3 3
2 3 1
3 1 1
3 1 2
1 3 1
1 1 2
1 2 2
1 3 2
1 2 1

样例输出

3
1
3
0
1
0
1
0
0
1


数据范围与提示

$1\leqslant N\leqslant 100,000$。

$1\leqslant K\leqslant 200,000$。

$1\leqslant s_i,c_i,m_i\leqslant K$。


题解

这道题好像可以用$bitset$,$CDQ$分治,$K-Dtree$解决。

$bitset$好像跑不过,我也不清楚……

最尴尬的是$K-Dtree$我不会……

那么我就来讲讲$CDQ$分治。

假设我们不考虑$m_i$,那么我们就变成了二元组排序,可以先将$s_i$排序,然后问题就转化成了:在一个数列里,找在$i$之前有几个数小于$c_i$。

很显然要使用树状数组维护即可在$\Theta (n\log n)$时间内求出答案。

那么现在又加了一维,怎么办呢?

首先,将这个三元组排序并去重,那么权值$a$已经随下标有序。

然后我们就需要引入$CDQ$分治,假设当前处理的区间为$[L,R]$其中点为$M$,那么我们在处理当前区间的时候已经保证了$[L,M]$和$[M+1,R]$的有序,因为$[L,M]$中的$s_i$一定小于等于$[M+1,R]$中的$s_i$,所以我们只需要维护一个单调指针,按照$[L,M]$中的$c_i$的大小从小到大将其放入树状数组,并在其中查询前缀和即可。


代码时刻

#include<bits/stdc++.h>
using namespace std;
struct rec
{
int s;
int c;
int m;
int x;
int id;
}e[2000001];
int n,k;
int tr[8000001];
int ans[2000001],q[2000001],b[2000001];
bool cmp1(rec a,rec b){return a.s<b.s||(a.s==b.s&&a.c<b.c)||(a.s==b.s&&a.c==b.c&&a.m<b.m);}
bool cmp2(rec a,rec b){return a.c<b.c||(a.c==b.c&&a.m<b.m)||(a.c==b.c&&a.m==b.m&&a.x<b.x);}
int lowbit(int x){return x&-x;}
void add(int x,int y)
{
while(x<=k)
{
tr[x]+=y;
x+=lowbit(x);
}
}
int query(int x)
{
int res=0;
while(x)
{
res+=tr[x];
x-=lowbit(x);
}
return res;
}
void cdq(int l,int r)//cdq分治
{
if(l==r)return;
int mid=(l+r)>>1;
cdq(l,mid);
cdq(mid+1,r);
sort(e+l,e+r+1,cmp2);
for(int i=l;i<=r;i++)
if(e[i].x<=mid)add(e[i].m,1);
else q[e[i].id]+=query(e[i].m);
for(int i=l;i<=r;i++)
if(e[i].x<=mid)add(e[i].m,-1);
}
int main()
{
scanf("%d%d",&n,&k);
for(int i=1;i<=n;i++)
{
scanf("%d%d%d",&e[i].s,&e[i].c,&e[i].m);
e[i].id=i;
}
sort(e+1,e+n+1,cmp1);
for(int i=1;i<=n;)//手动去重
{
int flag=i+1;
while(flag<=n&&e[i].s==e[flag].s&&e[i].c==e[flag].c&&e[i].m==e[flag].m)flag++;
flag--;
while(i<=flag)
{
b[e[i].id]=e[flag].id;
i++;
}
}
for(int i=1;i<=n;i++)e[i].x=i;
cdq(1,n);
for(int i=1;i<=n;i++)
ans[q[b[e[i].id]]]++;
for(int i=0;i<n;i++)
printf("%d\n",ans[i]);
return 0;
}

rp++

[BZOJ3262]:陌上花开(CDQ分治)的更多相关文章

  1. bzoj3262陌上花开 cdq分治

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

  2. bzoj3262陌上花开 cdq分治入门题

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

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

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

  4. bzoj3262 陌上花开 cdq分治(入门)

    题目传送门 思路:cdq分治处理偏序关系的模板题,主要就是学cdq分治吧,还在入门中. 代码其实也很好理解,记得树状数组操作的上限是 z的最大值,不是n的最大值,这个细节wa了好久. #include ...

  5. bzoj3262 陌上花开——CDQ分治

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3262 第一道CDQ分治题! 看博客:https://www.cnblogs.com/Narh ...

  6. 【学术篇】bzoj3262 陌上花开. cdq分治入门

    花儿们已经很累了-- 无论是花形.颜色.还是气味, 都不是为了给人们摆出来欣赏的, 更不是为了当做出题的素材的, 她们并不想自己这些属性被没有生命的数字量化, 并不想和其它的花攀比, 并无意分出个三六 ...

  7. BZOJ3262:陌上花开(CDQ分治)

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

  8. [Bzoj3262]陌上花开(CDQ分治&&树状数组||树套树)

    题目链接 题目就是赤裸裸的三维偏序,所以用CDQ+树状数组可以比较轻松的解决,但是还是树套树好想QAQ CDQ+树状数组 #include<bits/stdc++.h> using nam ...

  9. P3810 陌上花开 CDQ分治

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

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

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

随机推荐

  1. python multiprocessing模块 介绍

    一 multiprocessing模块介绍 python中的多线程无法利用多核优势,如果想要充分地使用多核CPU的资源(os.cpu\_count\(\)查看),在python中大部分情况需要使用多进 ...

  2. Linux Apache使用CGI

    CGI(Common Gateway Interface,通用网关接口)是网络服务器可以将查询传递到专门的程序中并且在网页上显示结果的标准机制.Apache等服务器默认是支持CGI的,只需要修改一下配 ...

  3. 万万没想到,Spring Boot 竟然这么耗内存!

    Spring Boot总体来说,搭建还是比较容易的,特别是Spring Cloud全家桶,简称亲民微服务. 但在发展趋势中,容器化技术已经成熟,面对巨耗内存的Spring Boot,小公司表示用不起. ...

  4. linux中断处理上下部分

    一.linux中断处理为什么要分为上下部 1.1. 中断处理的上半部(top half,又叫顶半部)和处理的下半部(bottom half,又叫底半部) 1.1. linux中断处理不参与调度,故中断 ...

  5. Java的同名属性、同名普通函数、同名静态函数,是否被覆盖

    作者按:虚拟函数的概念早就滚瓜烂熟了.但是今天面试发现:1.同名属性,2.同名普通函数,3.同名静态函数,是否被覆盖的问题.请看下面三个例子: 例子1:测试父类的属性是否存在和被完全覆盖class A ...

  6. css禁止鼠标双击选中文字

    div{ -moz-user-select:none;/*火狐*/ -webkit-user-select:none;/*webkit浏览器*/ -ms-user-select:none;/*IE10 ...

  7. elementUI 等 UI框架中,@change方法传递参数

      有些业务中,在使用 @change 回调的时候需要动态获取当前循环下的特定值,但是@change方法一旦传递参数就会覆盖原本的数据,对此,有两种方法解决: // 这种方法据说会改变 this 指向 ...

  8. 简单的物流项目实战,WPF的MVVM设计模式(四)

    接下来写ViewModels 创建运单的ViewModel类 public class CreateExpressWindowViewModel: NotificationObject { priva ...

  9. js实现完整轮播

    1.封装一个简单的动画函数 function animate(obj,target,callback){ clearInterval(obj.timer);//清除定时器防止定时器重复添加 obj.t ...

  10. 生成EXCEL文件是经常需要用到的功能,我们利用一些开源库可以很容易实现这个功能。

    方法一:利用excellibrary,http://code.google.com/p/excellibrary/ excellibrary是国人写的开源组件,很容易使用,可惜貌似还不支持.xlsx( ...