欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

BZOJ 3262: 陌上花开 (cdq分治,三维偏序)

程序员文章站 2022-05-14 18:56:45
...
#include <iostream>
#include <stdio.h>
#include <algorithm>
using namespace std;
 
const int maxn=1e5+10;
const int maxk=2e5+10;
 
int n,k;
 
struct Triple {
    int a,b,c,cnt,ans;
}a[maxn],A[maxn];
 
bool cmp(const Triple &a,const Triple &b) {
    if (a.a!=b.a) {
        return a.a<b.a;
    }
    else if (a.b!=b.b) {
        return a.b<b.b;
    }
    return a.c<b.c;
}
 
struct BitIndexTree {
    int a[maxk];
 
    int lowbit(const int x) {
        return x&(-x);
    }
 
    void Update(const int x,const int delta) {
        for (int i=x;i<=k;i+=lowbit(i)) {
            a[i]+=delta;
        }
    }
 
    void Clean(const int x) {
        for (int i=x;i<=k;i+=lowbit(i)) {
            if (a[i]) {
                a[i]=0;
            }
            else {
                break;
            }
        }
    }
 
    int Query(const int x) {
        int ans=0;
        for (int i=x;i>0;i-=lowbit(i)) {
            ans+=a[i];
        }
        return ans;
    }
}bit;   
 
void CDQ(Triple *l,Triple *r) 
{
    if (l==r) {
        l->ans+=l->cnt-1;
        return ;
    }
    Triple *mid=l+(r-l)/2;
    CDQ(l,mid);
    CDQ(mid+1,r);
 
    static Triple tmp[maxn];
    for (Triple *p=tmp,*p1=l,*p2=mid+1;p<=tmp+(r-l);p++) {
        if ((p1<=mid&&p1->b<=p2->b)||p2>r) {
            *p=*p1++;
            bit.Update(p->c,p->cnt);
        }
        else {
            *p=*p2++;
            p->ans+=bit.Query(p->c);
        }
    }
    for (Triple *p=tmp,*q=l;q<=r;p++,q++) {  
        bit.Clean(p->c);
        *q=*p;
    }
}
 
template <typename T>
inline void read(T &x) 
{
    int f=1;
    x=0;
    register char ch;
    ch=getchar();
    while (ch>'9'||ch<'0') {
        if (ch=='-') {
            f=-f;
        }
        ch=getchar();
    }
    while (ch>='0'&&ch<='9') {
        x=x*10+ch-'0';
        ch=getchar();
    }
    x*=f;
}
 
inline void write(int x)
{
    if (x<0) {
        putchar('-');
    }
    if (x>9) {
        write(x/10);
    }
    putchar(x%10+'0');
}
 
int main()
{
    scanf("%d%d",&n,&k);
    for (int i=0;i<n;i++) {
        read(a[i].a),read(a[i].b),read(a[i].c);
        // scanf("%d%d%d",&a[i].a,&a[i].b,&a[i].c);
        a[i].cnt=1;
    }
    sort(a,a+n,cmp);
    int cnt=0;
    for (int i=0;i<n;i++) {
        if (i==0||!(a[i].a==a[i-1].a&&a[i].b==a[i-1].b&&a[i].c==a[i-1].c)) {
            A[cnt++]=a[i];
        }
        else {
            A[cnt-1].cnt+=1;
        }
    }
    CDQ(A,A+cnt-1);
    static int ans[maxn];
    for (int i=0;i<cnt;i++) {
        ans[A[i].ans]+=A[i].cnt;
    }
    for (int i=0;i<n;i++) {
        write(ans[i]);
        putchar('\n');
        // printf("%d\n",ans[i]);
    }
    return 0;
}