BZOJ3262【CDQ分治】

注意三个属性完全相同的点.

/* I will wait for you */
 
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<ctime>
#include<algorithm>
#include<iostream>
#include<fstream>
#include<vector>
#include<queue>
#include<deque>
#include<set>
#include<map>
#include<string>
 
typedef long long LL;
typedef unsigned long long ULL;
 
using namespace std;
 
const int maxn=100010;
const int maxm=210;
const int maxs=26;
const int INF=1<<29;
const int P=1000000007;
const double error=1e-9;
 
struct flower{ int a,b,c,id,w,ans; }p[maxn],e[maxn];
 
int n,k,cnt=0,s[2*maxn],ans[maxn],fin[maxn];
 
bool cmpa(flower x,flower y)
{
    return x.a<y.a||x.a==y.a&&x.b<y.b||x.a==y.a&&x.b==y.b&&x.c<y.c;
}
 
bool cmpb(flower x,flower y)
{
    return x.b<y.b||x.b==y.b&&x.c<y.c;
}
 
void add(int x,int c)
{
    for(;x<=k;x+=x&(-x)) s[x]+=c;
}
 
int sum(int x)
{
    int ans=0;for(;x;x-=x&(-x)) ans+=s[x];return ans;
}
 
void slove(int l,int r)
{
    if(l==r) e[l].ans=e[l].w;
    else
    {
        int mid=(l+r)>>1,fi=l;
        slove(l,mid);slove(mid+1,r);
         
        sort(e+l,e+mid+1,cmpb);
        sort(e+mid+1,e+r+1,cmpb);
         
        for(int i=mid+1;i<=r;i++)
        {
            for(;fi<=mid&&e[fi].b<=e[i].b;fi++) add(e[fi].c,e[fi].w);
            e[i].ans+=sum(e[i].c);
        }
        for(int i=l;i<fi;i++) add(e[i].c,-e[i].w);   
    }
}   
 
int main()
{
    scanf("%d%d",&n,&k);
    for(int i=1;i<=n;i++) scanf("%d%d%d",&p[i].a,&p[i].b,&p[i].c);
     
    sort(p+1,p+1+n,cmpa);
     
    for(int i=1,wi=0;++wi&&i<=n;i++)
    {
        if(p[i].a!=p[i+1].a||p[i].b!=p[i+1].b||p[i].c!=p[i+1].c)
            e[++cnt]=p[i],e[cnt].id=cnt,e[cnt].w=wi,wi=0;
    }   
    slove(1,cnt);
 
    for(int i=1;i<=cnt;i++) fin[e[i].ans-1]+=e[i].w;
    for(int i=0;i<n;i++) printf("%d\n",fin[i]);
     
    return 0;
}

你可能感兴趣的:(BZOJ3262【CDQ分治】)