题目大意:给定一堆花,每个花有三个属性,定义一朵花比另一朵花美丽当期仅当三个值都大于等于另一朵花 定义花的评级为没有它美丽的花的数量 求评级为0~N-1的花的数量
CDQ分治的题,之前在HZWER神犇的博客里见到过,就写了写,今天BZ活了想去交才发现原来是只有会员才知道的世界。。。还好学校的大神有BZ的会员,借号交了下,半天过不去,最后发现原来我CDQ分治写脑残了。。。。妈妈再也不用担心我的学习了。。。
第一维排序,第二维CDQ分治,第三维树状数组,这题就切了
注意当两朵花的三个属性均相同两朵花互相比对方美丽 这个时候需要把这两朵花合并在一起处理 我这里还写挂了0.0 伤不起啊
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #define M 100100 using namespace std; struct abcd{ int x,y,z; int cnt,ans; }a[M],na[M]; bool operator < (const abcd &x,const abcd &y) { if(x.x==y.x) { if(x.y==y.y) return x.z<y.z; return x.y<y.y; } return x.x<y.x; } bool cmp(const abcd &x,const abcd &y) { if(x.y==y.y) { if(x.z==y.z) return x.x<y.x; return x.z<y.z; } return x.y<y.y; } int n,m,tot,T; int ans[M]; int c[M<<1],tim[M<<1]; void update(int x,int y) { for(;x<=m;x+=x&-x) { if(tim[x]!=T) c[x]=0; tim[x]=T; c[x]+=y; } } int getans(int x) { int re=0; for(;x;x-=x&-x) if(tim[x]==T) re+=c[x]; return re; } void CDQ(int l,int r) { int i,j,mid=l+r>>1; if(l==r) { a[mid].ans+=a[mid].cnt-1; return ; } int l1=l,l2=mid+1; for(i=l;i<=r;i++) { if(a[i].x<=mid) na[l1++]=a[i]; else na[l2++]=a[i]; } memcpy( a+l , na+l , sizeof(a[0])*(r-l+1) ); CDQ(l,mid); j=l;++T; for(i=mid+1;i<=r;i++) { for(;j<=mid&&a[j].y<=a[i].y;j++) update(a[j].z,a[j].cnt); a[i].ans+=getans(a[i].z); } CDQ(mid+1,r); l1=l;l2=mid+1; for(i=l;i<=r;i++) { if( ( cmp(a[l1],a[l2]) || l2>r ) && l1<=mid ) na[i]=a[l1++]; else na[i]=a[l2++]; } memcpy( a+l , na+l , sizeof(a[0])*(r-l+1) ); } int main() { int i; cin>>n>>m; for(i=1;i<=n;i++) scanf("%d%d%d",&a[i].x,&a[i].y,&a[i].z),a[i].cnt++; sort(a+1,a+n+1); for(i=1;i<=n;i++) { if( i==1 || a[i-1]<a[i] ) a[++tot]=a[i]; else a[tot].cnt++; } for(i=1;i<=tot;i++) a[i].x=i; sort(a+1,a+tot+1,cmp); CDQ(1,tot); for(i=1;i<=tot;i++) ans[ a[i].ans ]+=a[i].cnt; for(i=0;i<n;i++) printf("%d\n",ans[i]); }