BZOJ 3262 陌上花开

Posted on 2016-09-14 09:43  ziliuziliu  阅读(106)  评论(0编辑  收藏  举报

cdq做三维偏序。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define maxn 500500
#define maxw 500500
using namespace std;
int m,w,t[maxn],n=0,cnt=0,ans[maxn];
struct pnt
{
    int a,b,c,s,ans;
}p[maxn],q[maxn];
bool cmp1(pnt x,pnt y)
{
    if ((x.a==y.a) && (x.b==y.b)) return x.c<y.c;
    else if (x.a==y.a) return x.b<y.b;
    return x.a<y.a;
}
bool cmp2(pnt x,pnt y)
{
    if (x.b==y.b) return x.c<y.c;
    return x.b<y.b;
}
int lowbit(int x)
{
    return (x&(-x));
}
void update(int x,int val)
{
    for (int i=x;i<=w;i+=lowbit(i))
        t[i]+=val;
}
int ask(int x)
{
    int ret=0;
    for (int i=x;i>=1;i-=lowbit(i))
        ret+=t[i];
    return ret;
}
void cdq(int left,int right)
{
    if (left==right) return;
    int mid=left+right>>1;
    cdq(left,mid);cdq(mid+1,right);
    sort(q+left,q+mid+1,cmp2);sort(q+mid+1,q+right+1,cmp2);
    int i=left,j=mid+1;
    while (j<=right)
    {
        while ((i<=mid) && (q[i].b<=q[j].b))
        {
            update(q[i].c,q[i].s);
            i++;
        }
        q[j].ans+=ask(q[j].c);
        j++;
    }
    for (int j=left;j<i;j++)
        update(q[j].c,-q[j].s);
}
int main()
{
    scanf("%d%d",&m,&w);
    for (int i=1;i<=m;i++)
        scanf("%d%d%d",&p[i].a,&p[i].b,&p[i].c);
    sort(p+1,p+m+1,cmp1);
    for (int i=1;i<=m;i++)
    {
        cnt++;
        if ((p[i].a!=p[i+1].a) || (p[i].b!=p[i+1].b) || (p[i].c!=p[i+1].c))
        {
            q[++n]=p[i];
            q[n].s=cnt;
            cnt=0;
        }
    }
    cdq(1,n);
    for (int i=1;i<=n;i++)
        ans[q[i].ans+q[i].s-1]+=q[i].s;
    for (int i=0;i<m;i++) printf("%d\n",ans[i]);
    return 0;
}