BZOJ 3262: 陌上花开 CDQ分治


第一维排序,剩下两维用CDQ分治


3262: 陌上花开

Time Limit: 20 Sec   Memory Limit: 256 MB
Submit: 475   Solved: 216
[ Submit][ Status][ Discuss]

Description

有n朵花,每朵花有三个属性:花形(s)、颜色(c)、气味(m),又三个整数表示。现要对每朵花评级,一朵花的级别是它拥有的美丽能超过的花的数量。定义一朵花A比另一朵花B要美丽,当且仅当Sa>=Sb,Ca>=Cb,Ma>=Mb。显然,两朵花可能有同样的属性。需要统计出评出每个等级的花的数量。

Input

第一行为N,K (1 <= N <= 100,000, 1 <= K <= 200,000 ), 分别表示花的数量和最大属性值。
以下N行,每行三个整数si, ci, mi (1 <= si, ci, mi <= K),表示第i朵花的属性

Output

包含N行,分别表示评级为0...N-1的每级花的数量。

Sample Input

10 3
3 3 3
2 3 3
2 3 1
3 1 1
3 1 2
1 3 1
1 1 2
1 2 2
1 3 2
1 2 1

Sample Output

3
1
3
0
1
0
1
0
0
1

HINT

1 <= N <= 100,000, 1 <= K <= 200,000

Source

树套树 CDQ分治

[ Submit][ Status][ Discuss]


/* ***********************************************
Author        :CKboss
Created Time  :2015年08月02日 星期日 16时32分58秒
File Name     :BZOJ3262_2.cpp
************************************************ */

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <string>
#include <cmath>
#include <cstdlib>
#include <vector>
#include <queue>
#include <set>
#include <map>

using namespace std;

const int maxn=200200;

/*************BIT******************/
int tree[maxn],color[maxn],C;

inline int lowbit(int x) { return x&(-x); }

void Add(int p,int v)
{
	for(int i=p;i<maxn;i+=lowbit(i))
	{
		if(color[i]!=C) tree[i]=0;
		color[i]=C;
		tree[i]+=v;
	}
}

int Sum(int p)
{
	int ret=0;
	for(int i=p;i;i-=lowbit(i))
	{
		if(color[i]==C)
			ret+=tree[i];
	}
	return ret;
}

/****************NODE**************/

int n,S;

struct Flower
{
	int a,b,c,level,num;

	void toString()
	{
		printf("(%d,%d,%d) level: %d num: %d\n",a,b,c,level,num);
	}

}flower[maxn];

bool cmp(Flower a,Flower b){
	if (a.a==b.a && a.b==b.b) return a.c<b.c;
	if (a.a==b.a) return a.b<b.b;
	return a.a<b.a;
}

bool cmpCDQ(Flower a,Flower b){
	if (a.b==b.b) return a.c<b.c;
	return a.b<b.b;
}

/***************CDQ****************/

void CDQ(int left,int right)
{
    if(left==right) return ;
    int mid=(left+right)/2;
    CDQ(left,mid);CDQ(mid+1,right);
    sort(flower+left,flower+mid+1,cmpCDQ);
    sort(flower+mid+1,flower+right+1,cmpCDQ);
    int i,j;C++;
    for(j=mid+1,i=left;j<=right;j++)
    {
        for(;flower[i].b<=flower[j].b&&i<=mid;i++)
            Add(flower[i].c,flower[i].num);
        flower[j].level+=Sum(flower[j].c);
    }
}

int ans[maxn];

int main()
{
	//freopen("in.txt","r",stdin);
	//freopen("out.txt","w",stdout);

	scanf("%d%d",&n,&S);

	for(int i=1,a,b,c;i<=n;i++)
	{
		scanf("%d%d%d",&a,&b,&c);
		flower[i]=(Flower){a,b,c,0,1};
	}

	sort(flower+1,flower+n+1,cmp);

	int tot=1;
	for(int i=2;i<=n;i++)
	{
		if(flower[i].a!=flower[tot].a
				||(flower[i].b!=flower[tot].b)
				||(flower[i].c!=flower[tot].c))
		{
			tot++;
			flower[tot]=flower[i];
		}
		else
		{
			flower[tot].num++;
		}
	}

	CDQ(1,tot);

	for(int i=1;i<=tot;i++)
		ans[flower[i].level+flower[i].num-1]+=flower[i].num;
	for(int i=0;i<n;i++)
		printf("%d\n",ans[i]);

    return 0;
}



你可能感兴趣的:(BZOJ 3262: 陌上花开 CDQ分治)