• luogu3810 【模板】三维偏序(陌上花开)


    ref1
    ref2
    ref3
    ref4

    #include <algorithm>
    #include <iostream>
    #include <cstdio>
    using namespace std;
    int n, k, c[200005], cnt[200005];
    struct Node{
    	int x, y, z, idx, ans;
    	bool operator==(const Node &u)const{
    		return x==u.x && y==u.y && z==u.z;
    	}
    }a[100005], qwq, b[100005];
    bool cmp(const Node &u, const Node &v){
    	if(u.x!=v.x)	return u.x<v.x;
    	else if(u.y!=v.y)	return u.y<v.y;
    	else	return u.z<v.z;
    }
    int lb(int x){
    	return x & -x;
    }
    void add(int x, int v){
    	for(; x<=k; x+=lb(x))
    		c[x] += v;
    }
    int query(int x){
    	int re=0;
    	for(; x; x-=lb(x))
    		re += c[x];
    	return re;
    }
    void cdq(int l, int r){
    	if(l==r)	return ;
    	int mid=(l+r)>>1;
    	cdq(l, mid); cdq(mid+1, r);
    	int jj=l, kk=mid+1;
    	for(int i=l; i<=r; i++)
    		if(jj<=mid && (kk>r || a[jj].y<=a[kk].y))	b[i] = a[jj++];
    		else	b[i] = a[kk++];
    	for(int i=l; i<=r; i++){
    		a[i] = b[i];
    		if(a[i].idx<=mid)	add(a[i].z, 1);
    		else	a[i].ans += query(a[i].z);
    	}
    	for(int i=l; i<=r; i++)
    		if(a[i].idx<=mid)
    			add(a[i].z, -1);
    }
    int main(){
    	cin>>n>>k;
    	for(int i=1; i<=n; i++)
    		scanf("%d %d %d", &a[i].x, &a[i].y, &a[i].z);
    	sort(a+1, a+1+n, cmp);
    	int orzwys1996=1;
    	for(int i=n; i>=1; i--){
    		if(a[i]==qwq){
    			a[i].ans += orzwys1996;
    			orzwys1996++;
    		}
    		else{
    			qwq = a[i];
    			orzwys1996 = 1;
    		}
    		a[i].idx = i;
    	}
    	cdq(1, n);
    	for(int i=1; i<=n; i++)
    		cnt[a[i].ans]++;
    	for(int i=0; i<n; i++)
    		printf("%d
    ", cnt[i]);
    	return 0;
    }
    
  • 相关阅读:
    c++11:智能指针
    C++11:右值引用
    结构体与联合体
    数组与指针的区别?
    堆和栈的理论知识
    笔试点杂烩
    2、8、10、16进制输出
    单链表的反转
    签约新国都
    Linux下使用autoconf 和 automake 编译简单的HelloWorld
  • 原文地址:https://www.cnblogs.com/poorpool/p/8986177.html
Copyright © 2020-2023  润新知