BZOJ 3262 陌上花開 CDQ分治


題目大意:給定一堆花,每個花有三個屬性,定義一朵花比另一朵花美麗當期僅當三個值都大於等於另一朵花 定義花的評級為沒有它美麗的花的數量 求評級為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]);
}



注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
  © 2014-2022 ITdaan.com 联系我们: