陌上花开

第二遍写这个题了
题意:若某个元素的三个维度的值都小于等于另外一个元素,则是真的小于等于;给出一些元素,求等级分别为 0 <mtext>   </mtext> n 1 0~n-1 0 n1的元素数量;而一个元素的等级被定义为小于等于这个元素的元素数量。

思路:(⊙o⊙)…标准的板子,CDQ分治就是细节多一点

#include "bits/stdc++.h"
#define hhh printf("hhh\n")
#define see(x) (cerr<<(#x)<<'='<<(x)<<endl)
using namespace std;
typedef long long ll;
typedef pair<int,int> pr;
inline int read() {int x=0;char c=getchar();while(c<'0'||c>'9')c=getchar();while(c>='0'&&c<='9')x=x*10+c-'0',c=getchar();return x;}

const int maxn = 1e5+10;
const int mod = 1e9+7;
const double eps = 1e-9;

struct P{
    int x, y, z, cnt, rank;
    bool operator == (const P &rhs) const {
        return x==rhs.x&&y==rhs.y&&z==rhs.z;
    }
}p[maxn];

bool cmp1(const P &a, const P &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 cmp2(const P &a, const P &b) {
    return a.y<b.y;
}

int t[2*maxn], ans[maxn];
int n, k, tot;

inline void add(int x, int d) { while(x<=k) t[x]+=d, x+=x&-x; }
inline int sum(int x) { int ans=0; while(x) ans+=t[x], x-=x&-x; return ans; }

void solve(int l, int r) {
    if(l==r) {
        p[l].rank+=p[l].cnt-1;
        return;
    }
    int m=(l+r)/2;
    solve(l,m), solve(m+1,r);
    sort(p+l,p+m+1,cmp2), sort(p+m+1,p+r+1,cmp2);
    int j=l;
    for(int i=m+1; i<=r; ++i) {
        while(j<=m&&p[j].y<=p[i].y) add(p[j].z,p[j].cnt), ++j;
        p[i].rank+=sum(p[i].z);
    }
    while(--j>=l) add(p[j].z,-p[j].cnt);
}

int main() {
    //ios::sync_with_stdio(false); cin.tie(0);
    n=read(), k=read();
    for(int i=1; i<=n; ++i) {
        scanf("%d%d%d", &p[i].x, &p[i].y, &p[i].z);
        p[i].cnt=1, p[i].rank=0;
    }
    sort(p+1,p+1+n,cmp1);
    int last=1;
    for(int i=2; i<=n; ++i) {
        if(p[i]==p[last]) p[last].cnt++, p[i].cnt=0;
        else last=i;
    }
    for(int i=1; i<=n; ++i) if(p[i].cnt) p[++tot]=p[i];
    solve(1,tot);
    for(int i=1; i<=tot; ++i) ans[p[i].rank]+=p[i].cnt;
    for(int i=0; i<n; ++i) printf("%d\n", ans[i]);
}