BZOJ 3262 陌上花开(CDQ分治)
2016-04-07 10:31
423 查看
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
Solution
CDQ分治,以x,y,z表示一朵花的三个属性,以cnt[i]表示第i朵花的级别,按第一维排序,CDQ(l,r)表示求出[l,r]中所有元素对[l,r]中任一元素的贡献值,那么问题核心转化为如何求[l,mid]中所有元素对[mid+1,r]中任一元素的贡献值,由于[l,mid]中所有元素的第一维都不大于[mid+1,r]中所有元素的第一维,对两个区间都以第二维为第一关键字排序,对于每个[mid+1,r]中的元素i,将[l,mid]中所有满足j.y<=i.y的元素以j.z为下标,cnt[j]为键值插入到树状数组中,则只需统计树状数组中所有下标小于等于i.z的值之和累加到cnt[i]中即可
注意由于这个分治过程是有序的(按第一关键字分治),故如果两个元素的三个属性完全相同,那么在分治过程中编号靠前的元素的级别会少算,因为在计算其贡献的时候只考虑了编号在其前面的元素,故在分治前需要去重并统计每一个重复元素的数量,在分治结束之后再分别加上即可
Code
有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
Solution
CDQ分治,以x,y,z表示一朵花的三个属性,以cnt[i]表示第i朵花的级别,按第一维排序,CDQ(l,r)表示求出[l,r]中所有元素对[l,r]中任一元素的贡献值,那么问题核心转化为如何求[l,mid]中所有元素对[mid+1,r]中任一元素的贡献值,由于[l,mid]中所有元素的第一维都不大于[mid+1,r]中所有元素的第一维,对两个区间都以第二维为第一关键字排序,对于每个[mid+1,r]中的元素i,将[l,mid]中所有满足j.y<=i.y的元素以j.z为下标,cnt[j]为键值插入到树状数组中,则只需统计树状数组中所有下标小于等于i.z的值之和累加到cnt[i]中即可
注意由于这个分治过程是有序的(按第一关键字分治),故如果两个元素的三个属性完全相同,那么在分治过程中编号靠前的元素的级别会少算,因为在计算其贡献的时候只考虑了编号在其前面的元素,故在分治前需要去重并统计每一个重复元素的数量,在分治结束之后再分别加上即可
Code
#include<cstdio> #include<iostream> #include<algorithm> #include<cstring> using namespace std; #define maxn 222222 int n,tot,k,num[maxn]; struct node { int x,y,z,cnt,ans; }p[maxn]; int cmpx(node a,node b) { if(a.x!=b.x)return a.x<b.x; if(a.y!=b.y)return a.y<b.y; return a.z<b.z; } int cmpy(node a,node b) { if(a.y!=b.y)return a.y<b.y; return a.z<b.z; } struct BIT { #define lowbit(x) (x&(-x)) int b[maxn]; void init() { memset(b,0,sizeof(b)); } void update(int x,int v) { while(x<=k) { b[x]+=v; x+=lowbit(x); } } int query(int x) { int ans=0; while(x) { ans+=b[x]; x-=lowbit(x); } return ans; } void clear(int x) { while(x<=k) { b[x]=0; x+=lowbit(x); } } }bit; void CDQ(int l,int r) { if(l==r) { p[l].ans+=p[l].cnt-1; return ; } int mid=(l+r)>>1; CDQ(l,mid); CDQ(mid+1,r); sort(p+l,p+mid+1,cmpy); sort(p+mid+1,p+r+1,cmpy); int j=l; for(int i=mid+1;i<=r;i++) { for(;j<=mid&&p[j].y<=p[i].y;j++) bit.update(p[j].z,p[j].cnt); p[i].ans+=bit.query(p[i].z); } for(int i=l;i<j;i++)bit.update(p[i].z,-p[i].cnt); sort(p+l,p+r+1,cmpy); } int main() { bit.init();tot=0; memset(num,0,sizeof(num)); scanf("%d%d",&n,&k); for(int i=1;i<=n;i++) scanf("%d%d%d",&p[i].x,&p[i].y,&p[i].z),p[i].ans=1; sort(p+1,p+n+1,cmpx); for(int i=1;i<=n;i++) { if(i!=1&&p[i-1].x==p[i].x&&p[i-1].y==p[i].y&&p[i-1].z==p[i].z) p[tot].cnt++; else p[++tot]=p[i],p[tot].cnt=1; } CDQ(1,tot); sort(p+1,p+tot+1,cmpx); for(int i=1;i<=tot;i++)num[p[i].ans]+=p[i].cnt; for(int i=1;i<=n;i++)printf("%d\n",num[i]); return 0; }
相关文章推荐
- 彻底明白如何设置minSdkVersion和targetSdkVersion
- 42、Oracle 11g服务器安装详细步骤——图文教程
- VS应用程序无法启动0xc000007b
- Csdn 转载方法
- AD PCB制图问题解答
- android studio自定义属性使用
- 4.1.3.2 master_sigsetup函数:信号处理程序初始化
- android:layout_weight详细分析介绍
- android一些系统相关的东西
- 非阻塞SOCKET套接字connect等待时间的实现
- #if defined和#if !defined(c语言的宏定义)
- 2015最流行的Android组件、工具、框架大全
- Android中的Timer和Handler的使用
- 浮点数取模
- C++ 面试问题&资料整理
- minSdkVersion、targetSdkVersion、targetApiLevel的区别
- Office 365 ProPlus 安装及管理
- AutoCAD中ObjectARX C++常用的方法
- 【转】MyEclipse8.5集成Tomcat7时的启动错误:Exception in thread “main” java.lang.NoClassDefFoundError org/apache/commons/logging/LogFactory
- Cts框架解析(12)-ITargetPreparer