陌上花开 CDQ分治

传送门:https://www.luogu.org/problemnew/show/P3810

题意:

\[有n 个元素,第 i 个元素有 a_i、 b_i、 c_i 三个属性,设 f(i) 表示满足 a_j\leq a_i 且 b_j \leq b_i且 c_j \leq c_i的 j 的数量。\\
对于 d \in [0, n],求 f(i) = d 的数量
\]

题解:

CDQ分治模板题,

我们将第一维在主函数排序后,cdq分治里面,每次将左半边和右半边按照y排序,因为一开始的x是已经排序过了的,所以分治将其分为左半边和右半边时,左半边的x还是小于右半边的x,因此维护右半边的位置i和左半边的位置j,如果y[j]<y[i]的话,我们就可以将z[j]丢进树状数组中,直到y[j]>=y[i]时,不满足偏序关系的时候,我们就可以直接树状数组查询小于z[i]的前半部分的j的个数,这样,这么多个数就满足三维的偏序关系。

1.x的偏序关系已经在主函数里面处理,所以分治分了后前一半的x小于后一半的x

2.y的偏序关系是两个指针对着扫了,一遍,将满足y[j]<y[i]的z[j]丢进了树状数组统计个数

3.z的偏序关系是从树状数组中查的小于z[i]的z[j]有多少个

一直这样分治下去,我们就可以得到最终的答案

这个题有一个坑点就是,当x,y,z都相同时,在分治的时候,本来它们相互之间都有贡献,可是cdq的过程中只有左边的能贡献右边的。这可怎么办呢?我们直接离散化后,给定一个权值,这样算贡献就不会算错了

代码:

#include <set>
#include <map>
#include <cmath>
#include <cstdio>
#include <string>
#include <vector>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long LL;
typedef pair<int, int> pii;
typedef unsigned long long uLL;
#define ls rt<<1
#define rs rt<<1|1
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
#define bug printf("*********\n")
#define FIN freopen("input.txt","r",stdin);
#define FON freopen("output.txt","w+",stdout);
#define IO ios::sync_with_stdio(false),cin.tie(0)
#define debug1(x) cout<<"["<<#x<<" "<<(x)<<"]\n"
#define debug2(x,y) cout<<"["<<#x<<" "<<(x)<<" "<<#y<<" "<<(y)<<"]\n"
#define debug3(x,y,z) cout<<"["<<#x<<" "<<(x)<<" "<<#y<<" "<<(y)<<" "<<#z<<" "<<z<<"]\n"
const int maxn = 3e5 + 5;
const int INF = 0x3f3f3f3f;
struct node {
int x, y, z;
int cnt;
int ans;
} a[maxn];
bool cmpx(node a, node b) {
if(a.x == b.x && a.y == b.y) return a.z < b.z;
if(a.x == b.x) return a.y < b.y;
return a.x < b.x;
}
bool cmpy(node a, node b) {
if(a.y == b.y && a.z == b.z) return a.x < b.x;
if(a.y == b.y) return a.z < b.z;
return a.y < b.y;
}
int lowbit(int x) {
return x & (-x);
}
int bit[maxn];
void add(int pos, int val) {
while(pos < maxn) {
bit[pos] += val;
pos += lowbit(pos);
}
}
int sum(int pos) {
int res = 0;
while(pos) {
res += bit[pos];
pos -= lowbit(pos);
}
return res;
}
int num[maxn];
void CDQ(int l, int r) {
if(l == r) {
a[l].ans += a[l].cnt - 1;
return;
}
int mid = (l + r) >> 1;
CDQ(l, mid);
CDQ(mid + 1, r);
sort(a + l, a + mid + 1, cmpy);
sort(a + mid + 1, a + r + 1, cmpy);
int j = l;
for(int i = mid + 1; i <= r; i++) {
while(j <= mid && a[j].y <= a[i].y) {
add(a[j].z, a[j].cnt);
j++;
}
a[i].ans += sum(a[i].z);
}
for(int i = l; i < j; i++) {
add(a[i].z, -a[i].cnt);
}
}
int main() {
#ifndef ONLINE_JUDGE
FIN
#endif
int n, k;
scanf("%d%d", &n, &k);
for(int i = 1; i <= n; i++) {
scanf("%d%d%d", &a[i].x, &a[i].y, &a[i].z);
a[i].ans = 1;
}
sort(a + 1, a + n + 1, cmpx);
int tot = 0;
for(int i = 1; i <= n; ++i) {
if(i != 1 && a[i].x == a[i - 1].x && a[i].y == a[i - 1].y && a[i].z == a[i - 1].z) a[tot].cnt++;
else a[++tot] = a[i], a[tot].cnt = 1;
}
CDQ(1, tot);
sort(a + 1, a + tot + 1, cmpx);
for(int i = 1; i <= tot; i++) {
num[a[i].ans] += a[i].cnt;
}
for(int i = 1; i <= n; i++) {
printf("%d\n", num[i]);
}
return 0;
}

P3810 陌上花开 CDQ分治的更多相关文章

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

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

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

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

  3. bzoj3262陌上花开 cdq分治

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

  4. 【CJOJ2433】陌上花开 CDQ分治

    [CJOJ2433]陌上花开 CDQ呲嘚秋分治 WA果然呲嘚秋分治跑得比树套树还快!!!(md理论复杂度不是一样的吗) 但树套树不知道比呲嘚秋高到哪里去辣装X用 Orz hzwer 第一维sort,第 ...

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

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

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

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

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

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

  8. bzoj 3262 陌上花开 - CDQ分治 - 树状数组

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

  9. 陌上花开——CDQ分治

    传送门 “CDQ分治”从来都没有听说过,写了这题才知道还有这么神奇的算法. (被逼无奈).w(゚Д゚)w 于是看了不少dalao的博客,对CDQ算法粗浅地了解了一点.(想要了解CDQ的概念,可以看下这 ...

随机推荐

  1. 比较全面的一个PHP缓存类解析

    转自:http://www.blhere.com/1164.html 一.引论 PHP,一门最近几年兴起的web设计脚本语言,由于它的强大和可伸缩性,近几年来得到长足的发展,php相比传统的asp网站 ...

  2. linux包之包管理rpm-yum

    背景 YUM(Yellow dog Updater, Modified)为多个Linux发行版的前端软件包管理器,例如 Redhat RHEL, CentOS & Fedora. YUM通过调 ...

  3. 2019-8-29-dotnet-core-使用-sqlite-部署到-Centos-服务器

    title author date CreateTime categories dotnet core 使用 sqlite 部署到 Centos 服务器 lindexi 2019-08-29 19:1 ...

  4. hdu 1561【树形dp+01背包】

    http://acm.hdu.edu.cn/showproblem.php?pid=1561 很容易想到如果是要攻克v城需要先攻克u城的话,可以建u到v的边.但是如果能够直接攻克u城呢?无边可建,这样 ...

  5. Git 的两种忽略文件方式 gitignore 和 exclude

    Git 的两种忽略文件方式 gitignore 和 exclude .gitignore 不用说了,大家都知道. 有一个 exclude 可能接触比较少. 知道这个功能后发现,用在服务器上非常方便,因 ...

  6. tensorflow学习笔记(三十四):Saver(保存与加载模型)

    Savertensorflow 中的 Saver 对象是用于 参数保存和恢复的.如何使用呢? 这里介绍了一些基本的用法. 官网中给出了这么一个例子: v1 = tf.Variable(..., nam ...

  7. Hbase数据模型 时间戳

  8. chrome谷歌浏览器怎么清除指定网站cookie

    https://jingyan.baidu.com/article/fa4125aced30cc28ac709230.html 在使用电脑的情况下,由于到部分网站的cookie的问题导致的部分功能失效 ...

  9. Mac 安装homebrew,pkgutil --pkgs列出安装包

    Mac 安装homebrew Homebrew官网 http://brew.sh/index_zh-cn.html Homebrew是神马 Linux系统有个让人蛋疼的通病,软件包依赖,好在当前主流的 ...

  10. HTML--简单的注册网页

    利用表格,渐变色 <body background="未标题-2.jpg"> <table align="center" border=&qu ...