裸的cdq,注意去重;

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=100010,maxm=200010;
int tot,n,k,tr[maxm],h[maxn],t1,t2,len1,len2,ans[maxn];
void add(int pos,int v){
    for(int i=pos;i<maxm;i+=i&(-i))
    tr[i]+=v;
}
int qs(int pos){
    int res=0;
    for(int i=pos;i;i-=i&(-i))
    res+=tr[i];
    return res;
}
struct node{
    int ls,lc,lm,id,cnt;
}tt[maxn],t[maxn],tmp1[maxn],tmp2[maxn];
int cmp1(node a,node b){
    if(a.lm!=b.lm)return a.lm<b.lm;
    if(a.lc!=b.lc)return a.lc<b.lc;
    return a.ls<b.ls;
}
int cmp2(node a,node b){
    if(a.lc!=b.lc)return a.lc<b.lc;
    return a.ls<b.ls;
}
void cdq(int l,int r){
    if(l==r){
        h[t[l].id]+=t[l].cnt-1;
        return;
    }
    int mid=l+r>>1;
    cdq(l,mid);cdq(mid+1,r);
    t1=t2=0;
    for(int i=l;i<=mid;++i)tmp1[++t1]=t[i];
    for(int i=mid+1;i<=r;++i)tmp2[++t2]=t[i];
    sort(tmp1+1,tmp1+t1+1,cmp2);
    sort(tmp2+1,tmp2+t2+1,cmp2);
    len1=t1,len2=t2;
    t1=t2=1;
    for(t2=1;t2<=len2;++t2){
        while(tmp1[t1].lc<=tmp2[t2].lc&&t1<=len1){
            add(tmp1[t1].ls,tmp1[t1].cnt);++t1;
        }
        h[tmp2[t2].id]+=qs(tmp2[t2].ls);
    }
    for(int i=1;i<t1;++i)add(tmp1[i].ls,-tmp1[i].cnt);
}
int main(){
    cin>>n>>k;
    for(int i=1;i<=n;++i){
        scanf("%d%d%d",&tt[i].ls,&tt[i].lc,&tt[i].lm);
    }
    sort(tt+1,tt+n+1,cmp1);
    for(int i=1;i<=n;++i){
        if(i!=1&&tt[i-1].lm==tt[i].lm&&tt[i-1].ls==tt[i].ls&&tt[i-1].lc==tt[i].lc){
            t[tot].cnt++;
        }
        else t[++tot]=tt[i],t[tot].cnt=1;
    }
    for(int i=1;i<=tot;++i)t[i].id=i;
    cdq(1,tot);
    for(int i=1;i<=tot;++i){
        ans[h[i]]+=t[i].cnt;
    }
    for(int i=0;i<n;++i){
        printf("%d\n",ans[i]);
    }
    system("pause");
    return 0;
}

 

posted on 2017-12-22 19:37  湮灭之瞳  阅读(165)  评论(0编辑  收藏  举报