三维偏序[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)\)的代价使动态 ...
随机推荐
- Flutter开发之Widget学习
一.Text 组件 属性 textAlign: TextAlign.left, -----文本对齐方式 maxLines: 1, ...
- k3s首季在线培训来袭!本周四晚,线上见!
筹备已久的k3s在线培训终于要和大家见面啦! k3s是一款适用于边缘计算场景以及IoT场景的轻量级Kubernetes发行版,经过CNCF的一致性认证.由业界应用最广泛的Kubernetes管理平台R ...
- HDU_3853_区间dp
http://acm.hdu.edu.cn/showproblem.php?pid=3853 dp[i][j]表示由空白串刷成b的从i到j位所需要的最小次数. 然后在比较a和b的每一位,再次更新dp表 ...
- Codeforces Round #620 F2. Animal Observation (hard version) (dp + 线段树)
Codeforces Round #620 F2. Animal Observation (hard version) (dp + 线段树) 题目链接 题意 给定一个nm的矩阵,每行取2k的矩阵,求总 ...
- BZOJ 2434 阿狸的打字机(ac自动机+dfs序+树状数组)
题意 给你一些串,还有一些询问 问你第x个串在第y个串中出现了多少次 思路 对这些串建ac自动机 根据fail树的性质:若x节点是trie中root到t任意一个节点的fail树的祖先,那么x一定是y的 ...
- mysql和 oracle 的区别
垂直拆分: 把一个数据库中不同业务单元的数据分到不同的数据库里面.水平拆分: 根据一定的规则把同一业务单元的数据拆分到多个数据库中. 读写分离 主:写 从:查 ==================== ...
- Go语言实现:【剑指offer】最小的K个数
该题目来源于牛客网<剑指offer>专题. 输入n个整数,找出其中最小的K个数.例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4,. Go语言实现: fu ...
- Go语言实现:【剑指offer】用两个栈实现队列
该题目来源于牛客网<剑指offer>专题. 用两个栈来实现一个队列,完成队列的Push和Pop操作. 队列中的元素为int类型. Go语言实现: var list1 = list.New( ...
- 如何查看MySql的sql语句性能
原文链接:https://blog.csdn.net/jwq101666/article/details/78561022Explain命令在解决数据库性能上是第一推荐使用命令,大部分的性能问题可以通 ...
- ## springboot 下策略模式的简单使用
1.灵魂三问 接手前人(已跑路)项目快乐否? 前人项目不写注释懵逼否? 一个方法中一堆if/else,且业务判断条件用简单数字(或英文字母),不带注释,想打人否? 所以,对于上述三个问题,我写 ...