三维偏序[cdq分治学习笔记]
就是让第一维有序 然后归并+树状数组求两维
cdq+cdq不会 告辞
#include <bits/stdc++.h>
// #define int long long
#define rep(a , b , c) for(int a = b ; a <= c ; ++ a)
#define Rep(a , b , c) for(int a = b ; a >= c ; -- a)
#define go(u) for(int i = G.head[u] , v = G.to[i] , w = G.dis[i] ; i ; v = G.to[i = G.nxt[i]] , w = G.dis[i])
using namespace std ;
using ll = long long ;
using pii = pair < int , int > ;
using vi = vector < int > ;
int read() {
int x = 0 ; bool f = 1 ; char c = getchar() ;
while(c < 48 || c > 57) { if(c == '-') f = 0 ; c = getchar() ; }
while(c > 47 && c < 58) { x = (x << 1) + (x << 3) + (c & 15) ; c = getchar() ; }
return f ? x : -x ;
}
template <class T> void print(T x , char c = '\n') {
static char st[100] ; int stp = 0 ;
if(! x) { putchar('0') ; }
if(x < 0) { x = -x ; putchar('-') ; }
while(x) { st[++ stp] = x % 10 ^ 48 ; x /= 10 ; }
while(stp) { putchar(st[stp --]) ; } putchar(c) ;
}
template <class T> void cmax(T & x , T y) { x < y ? x = y : 0 ; }
template <class T> void cmin(T & x , T y) { x > y ? x = y : 0 ; }
const int _N = 1e6 + 10 ;
struct Group {
int head[_N] , nxt[_N << 1] , to[_N] , dis[_N] , cnt = 1 ;
Group () { memset(head , 0 , sizeof(head)) ; }
void add(int u , int v , int w = 1) { nxt[++ cnt] = head[u] ; to[cnt] = v ; dis[cnt] = w ; head[u] = cnt ; }
} ;
const int N = 1e5 + 10 ;
typedef int arr[N] ;
int n , k ;
struct Node {
int x , y , z , ans , cnt ;
Node() {}
bool operator < (const Node & other) const {
if(x != other.x) return x < other.x ;
if(y != other.y) return y < other.y ;
return z < other.z ;
}
bool operator == (const Node & other) const {
return (x == other.x) && (y == other.y) && (z == other.z) ;
}
} a[N] , b[N] , tmp[N] ;
struct BIT {
int c[N << 1] , mxk ;
int low(int x) {
return x & - x ;
}
void add(int x , int y) {
if(! x) return ;
for( ; x <= mxk ; x += low(x)) c[x] += y ;
}
int query(int x) {
int ans = 0 ;
for( ; x ; x ^= low(x)) ans += c[x] ;
return ans ;
}
} t ;
bool cmp(Node x , Node y) {
if(x.y != y.y) return x.y < y.y ;
if(x.z != y.z) return x.z < y.z ;
}
void solve(int l , int r){
// printf("%d -> %d\n" , l , r) ;
if(l == r) return ;
int mid = l + r >> 1 ;
solve(l , mid) ; solve(mid + 1 , r) ;
int p = l ; rep(i , mid + 1 , r) {
for( ; b[p].y <= b[i].y && p <= mid ; ++ p) t.add(b[p].z , b[p].cnt) ;
b[i].ans += t.query(b[i].z) ;
}
rep(i , l , p - 1) t.add(b[i].z , -b[i].cnt) ;
merge(b + l , b + mid + 1 , b + mid + 1 , b + r + 1 , tmp , cmp) ;
rep(i , l , r) b[i] = tmp[i - l] ;
// printf("%d -> %d\n" , l , r) ;
}
int ans[N] ;
signed main() {
n = read() ; t.mxk = k = read() ;
rep(i , 1 , n) { a[i].x = read() ; a[i].y = read() ; a[i].z = read() ; }
sort(a + 1 , a + n + 1) ; rep(i , 1 , n) b[i] = a[i] ;
int len = unique(b + 1 , b + n + 1) - b - 1 ; int tp = 1 ;
rep(i , 1 , n) if(a[i] == b[tp]) ++ b[tp].cnt ; else ++ b[++ tp].cnt ;
solve(1 , len) ;
rep(i , 1 , len) { ans[b[i].ans + b[i].cnt - 1] += b[i].cnt ; }
rep(i , 0 , n - 1) print(ans[i]) ;
return 0 ;
}
先咕着
三维偏序[cdq分治学习笔记]的更多相关文章
- Luogu 3810 & BZOJ 3262 陌上花开/三维偏序 | CDQ分治
Luogu 3810 & BZOJ 3263 陌上花开/三维偏序 | CDQ分治 题面 \(n\)个元素,每个元素有三个值:\(a_i\), \(b_i\) 和 \(c_i\).定义一个元素的 ...
- CDQ分治学习笔记(三维偏序题解)
首先肯定是要膜拜CDQ大佬的. 题目背景 这是一道模板题 可以使用bitset,CDQ分治,K-DTree等方式解决. 题目描述 有 nn 个元素,第 ii 个元素有 a_iai.b_ibi.c_ ...
- 初学cdq分治学习笔记(可能有第二次的学习笔记)
前言骚话 本人蒟蒻,一开始看到模板题就非常的懵逼,链接,学到后面就越来越清楚了. 吐槽,cdq,超短裙分治....(尴尬) 正片开始 思想 和普通的分治,还是分而治之,但是有一点不一样的是一般的分治在 ...
- CDQ分治学习笔记
数据结构中的一块内容:$CDQ$分治算法. $CDQ$显然是一个人的名字,陈丹琪(NOI2008金牌女选手) 这种离线分治算法被算法界称为"cdq分治" 我们知道,一个动态的问题一 ...
- bzoj3262: 陌上花开 三维偏序cdq分治
三维偏序裸题,cdq分治时,左侧的x一定比右侧x小,然后分别按y排序,对于左侧元素按y大小把z依次插入到树状数组里,其中维护每个左侧元素对右侧元素的贡献,在bit查询即可 /************* ...
- [bzoj] 3263 陌上花开 洛谷 P3810 三维偏序|| CDQ分治 && CDQ分治讲解
原题 定义一个点比另一个点大为当且仅当这个点的三个值分别大于等于另一个点的三个值.每比一个点大就为加一等级,求每个等级的点的数量. 显然的三维偏序问题,CDQ的板子题. CDQ分治: CDQ分治是一种 ...
- BZOJ3262 陌上花开 —— 三维偏序 CDQ分治
题目链接:https://vjudge.net/problem/HYSBZ-3262 3262: 陌上花开 Time Limit: 20 Sec Memory Limit: 256 MBSubmit ...
- BZOJ 3295:[Cqoi2011]动态逆序对(三维偏序 CDQ分治+树状数组)
http://www.lydsy.com/JudgeOnline/problem.php?id=3295 题意:简单明了. 思路:终于好像有点明白CDQ分治处理三维偏序了.把删除操作看作是插入操作,那 ...
- [摸鱼]cdq分治 && 学习笔记
待我玩会游戏整理下思绪(分明是想摸鱼 cdq分治是一种用于降维和处理对不同子区间有贡献的离线分治算法 对于常见的操作查询题目而言,时间总是有序的,而cdq分治则是耗费\(O(logq)\)的代价使动态 ...
随机推荐
- RabbitMQ下载与安装
RabbitMQ下载与安装 先跟大家科普一下MQ和RabbitMQ MQ简介 MQ全称为Message Queue ,即消息队列 应用场景: 1.任务异步处理. 将不需要同步处理的并且耗时长的操作由消 ...
- LIBCMTD.lib与libcpmtd冲突的解决方法。
error: 1>uafxcwd.lib(afxmem.obj) : error LNK2005: "void * __cdecl operator new(unsigned int) ...
- [web]2019第一起数据泄露事件
-rwxrwxrwx 33405108 Jan 22 2016 000webhost.txt -rwxrwxrwx 165025 Jul 29 2017 01nii.ru {1.931} [HASH] ...
- 51Nod 1021 石子归并(区间dp经典入门)
题意: N堆石子摆成一条线.现要将石子有次序地合并成一堆.规定每次只能选相邻的2堆石子合并成新的一堆,并将新的一堆石子数记为该次合并的代价.计算将N堆石子合并成一堆的最小代价. n<=100 思 ...
- Element ui select 同时获取value和label的值
html <el-form-item label="单位名称" prop="checkInUnitName"> <el-select v-mo ...
- Go语言实现:【剑指offer】字符流中第一个不重复的字符
该题目来源于牛客网<剑指offer>专题. 请实现一个函数用来找出字符流中第一个只出现一次的字符.例如,当从字符流中只读出前两个字符"go"时,第一个只出现一次的字符是 ...
- 2020.2.22 bzoj5336 party
#include<iostream> #include<cstdio> #include<cstring> #include<cctype> #incl ...
- Metasploit学习笔记(一) Samba服务 usermap_script安全漏洞相关信息
一.Samba介绍 Samba是linux和unix系统上实现smb协议的一个免费软件,由客户机和服务器构成.SMB是一种在局域网上实现共享文件和打印机的协议.存在一个服务器,客户机通过该协议可以服务 ...
- rsync命令 SCP命令
快速查询scp: scp 各种参数 源地址文件 目的地址文件 从本地复制到远程: scp [[user@]host1:]file1 ... [[user@]h ...
- Oracle 重启监听
对于DBA来说,启动和关闭oracle监听器是很基础的任务,但是Linux系统管理员或者程序员有时也需要在开发数据库中做一些基本的DBA操作,因此了解一些基本的管理操作对他们来说很重要. 本文将讨论用 ...