ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

洛谷 P3810 【模板】三维偏序(陌上花开)

2022-09-09 23:33:24  阅读:212  来源: 互联网

标签:偏序 count cnt return int tt P3810 洛谷 rep


原题链接
第一维直接排序,然后cdq分治+树状数组
对于分治的左右区间,区间内部按照第二维排序(已按第一维排序好了,就算打乱顺序,左右区间整体的第一维的偏序关系也不会受到影响)
然后遍历右区间的元素,把左区间的第二维小于当前元素的加入树状数组,统计答案即可,因为区间内部第二维都是单调不递减的,只需遍历一遍

#include<bits/stdc++.h>
using namespace std;

#define fr first
#define se second
#define et0 exit(0);
#define rep(i, a, b) for(int i = (int)(a); i <= (int)(b); i ++)
#define rrep(i, a, b) for(int i = (int)(a); i >= (int)(b); i --)
#define IO ios::sync_with_stdio(false),cin.tie(0);

typedef long long LL;
typedef pair<int, int> PII;
typedef pair<LL, LL> PLL;
typedef unsigned long long ULL;

const int INF = 0X3f3f3f3f, N = 2e5 + 10, MOD = 1e9 + 7;
const double eps = 1e-7, pi = acos(-1);

int n, k;

struct NODE{
	int x, y, z, cnt, res;	
}a[N], b[N];

bool cmp1(NODE &A, NODE &B) {
	if (A.x == B.x) {
		if (A.y == B.y) return A.z < B.z;
		return A.y < B.y;
	}
	return A.x < B.x;
}

bool cmp2(NODE &A, NODE &B) {
	if (A.y == B.y) return A.z < B.z;
	return A.y < B.y;
}

int tr[N];

int lowbit(int x){
    return x & -x;
}

void insert(int x, int c){
    for(int i = x; i <= k; i += lowbit(i)) tr[i] += c;
}

int query(int x){
    int res = 0;
    for(int i = x; i >= 1; i -= lowbit(i)) res += tr[i];
    return res;
}

void cdq(int l, int r) {
	if (l == r) return;
	int mid = l + r >> 1;
	cdq(l, mid), cdq(mid + 1, r);
	
	sort(b + l, b + mid + 1, cmp2);
	sort(b + mid + 1, b + r + 1, cmp2);
	
	int tt = l;
	rep (i, mid + 1, r) {
		while (tt <= mid && b[i].y >= b[tt].y) {
			insert(b[tt].z, b[tt].cnt);
			tt++;
		}
		b[i].res += query(b[i].z);
	}
	rep (i, l, tt - 1) insert(b[i].z, -b[i].cnt);
}

void work() {
	cin >> n >> k;
	rep (i, 1, n) cin >> a[i].x >> a[i].y >> a[i].z;
	sort(a + 1, a + 1 + n, cmp1);
	int count = 0;
	rep (i, 1, n) {
		if (a[i].x != b[count].x || a[i].y != b[count].y || a[i].z != b[count].z) {
			count++;
			b[count].x = a[i].x, b[count].y = a[i].y, b[count].z = a[i].z;
			b[count].cnt = 1;
		}
		else b[count].cnt++;
	}
	cdq(1, count);
	vector<int> ans(n + 1);
	rep (i, 1, count) ans[b[i].res + b[i].cnt - 1] += b[i].cnt;
	rep (i, 0, n - 1) cout << ans[i] << endl;
}

signed main() {
	IO

	int test = 1;

	while (test--) {
		work();
	}

	return 0;
}

标签:偏序,count,cnt,return,int,tt,P3810,洛谷,rep
来源: https://www.cnblogs.com/xhy666/p/16675549.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有