陌上花开 HYSBZ - 3262

https://www.lydsy.com/JudgeOnline/problem.php?id=3262

三维偏序 就是相同元素的处理比较麻烦 可以把相同元素的数量作为权值更新到线段树里

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

struct node0
{
    int id;
    int a;
    int b;
    int c;
};

struct node1
{
    int tp;
    int x;
    int y;
    int val;
};

struct node2
{
    int l;
    int r;
    int val;
};

node0 pre[400010];
node1 order[400010],tmp[400010];
node2 tree[1600010];
int gou[400010],ans[400010],book[400010];
int n,nn,k,tot;

bool cmp(node0 n1,node0 n2)
{
    if(n1.a==n2.a)
    {
        if(n1.b==n2.b) return n1.c<n2.c;
        else return n1.b<n2.b;
    }
    else return n1.a<n2.a;
}

void build(int l,int r,int cur)
{
    int m;
    tree[cur].l=l;
    tree[cur].r=r;
    tree[cur].val=0;
    if(l==r) return;
    m=(l+r)/2;
    build(l,m,2*cur);
    build(m+1,r,2*cur+1);
}

void update(int tar,int val,int cur)
{
    tree[cur].val+=val;
    if(tree[cur].l==tree[cur].r) return;
    if(tar<=tree[2*cur].r) update(tar,val,2*cur);
    else update(tar,val,2*cur+1);
}

int query(int pl,int pr,int cur)
{
    int res;
    if(pl<=tree[cur].l&&tree[cur].r<=pr)
    {
        return tree[cur].val;
    }
    res=0;
    if(pl<=tree[2*cur].r) res+=query(pl,pr,2*cur);
    if(pr>=tree[2*cur+1].l) res+=query(pl,pr,2*cur+1);
    return res;
}


void cdq(int l,int r)
{
    int m,p,q,cnt,i;
    if(l==r) return;
    m=(l+r)/2;
    cdq(l,m);
    cdq(m+1,r);
    p=l,q=m+1,cnt=l;
    while(p<=m&&q<=r)
    {
        if(order[p].x<=order[q].x)
        {
            if(order[p].tp==1) update(order[p].y,order[p].val,1);
            tmp[cnt++]=order[p++];
        }
        else
        {
            if(order[q].tp==2) gou[order[q].val]+=query(1,order[q].y,1);
            tmp[cnt++]=order[q++];
        }
    }
    while(q<=r)
    {
        if(order[q].tp==2) gou[order[q].val]+=query(1,order[q].y,1);
        tmp[cnt++]=order[q++];
    }
    for(i=l;i<p;i++)
    {
        if(order[i].tp==1) update(order[i].y,-order[i].val,1);
    }
    while(p<=m) tmp[cnt++]=order[p++];
    for(i=l;i<=r;i++) order[i]=tmp[i];
}

int main()
{
    int i,j,p,a,b,c;
    scanf("%d%d",&n,&k);
    for(i=1;i<=n;i++)
    {
        pre[i].id=i;
        scanf("%d%d%d",&pre[i].a,&pre[i].b,&pre[i].c);
    }
    sort(pre+1,pre+n+1,cmp);
    nn=0,p=1;
    for(i=1;i<=n;i++)
    {
        if(!(pre[i].a==pre[nn].a&&pre[i].b==pre[nn].b&&pre[i].c==pre[nn].c)) pre[++nn]=pre[i];
        book[nn]++;
    }
    tot=0;
    for(i=1;i<=nn;i++)
    {
        tot++;
        order[tot].tp=1,order[tot].x=pre[i].b,order[tot].y=pre[i].c,order[tot].val=book[i];
        tot++;
        order[tot].tp=2,order[tot].x=pre[i].b,order[tot].y=pre[i].c,order[tot].val=i;
    }
    build(1,k,1);
    cdq(1,tot);
    for(i=1;i<=nn;i++)
    {
        for(j=0;j<book[i];j++) ans[gou[i]]++;
    }
    for(i=1;i<=n;i++) printf("%d\n",ans[i]);
    return 0;
}

/*
5 5
1 1 1
2 2 2
2 2 2
3 3 3
3 3 3
*/

猜你喜欢

转载自blog.csdn.net/sunyutian1998/article/details/81985921