首页 > 代码库 > 【三维偏序】【分块】bzoj3262 陌上花开
【三维偏序】【分块】bzoj3262 陌上花开
裸的三维偏序。 对x坐标排序,y、z坐标分块。复杂度O(n*sqrt(n*log(n)))。代码很短。
1 #include<cstdio> 2 #include<cmath> 3 #include<algorithm> 4 #include<vector> 5 using namespace std; 6 struct Point{int x,y,z,num;void Read(){scanf("%d%d%d",&x,&y,&z);}}p[100002]; 7 bool operator < (const Point &a,const Point &b){return a.x<b.x;} 8 bool cmp (const Point &a,const Point &b){return a.y<b.y;} 9 vector<int>b[400];10 vector<Point>a[400];11 int n,rank[100001],m,head,maxv[400],sum;12 void makeblock()13 {14 int sz=(int)sqrt((double)n*(log((double)n)/log(2.0))); if(!sz) sz=1;15 for(sum=1;sum*sz<n;sum++)16 {17 int R=sum*sz;18 for(int i=(sum-1)*sz+1;i<=R;i++) p[i].num=sum;19 maxv[sum]=p[R].y;20 }21 for(int i=(sum-1)*sz+1;i<=n;i++) p[i].num=sum;22 maxv[sum]=p[n].y;23 }24 void insert(const Point &U)25 {26 b[U.num].insert(upper_bound(b[U.num].begin(),b[U.num].end(),U.z),U.z);27 a[U.num].push_back(U);28 }29 int query(const Point &U)30 {31 int cnt=0,i;32 for(i=1;i<=sum && maxv[i]<=U.y;++i)33 cnt+=upper_bound(b[i].begin(),b[i].end(),U.z)-b[i].begin();34 for(vector<Point>::iterator it=a[i].begin();it!=a[i].end();++it)35 if((*it).z<=U.z&&(*it).y<=U.y) ++cnt;36 return cnt;37 }38 int main()39 {40 scanf("%d%d",&n,&m);41 for(int i=1;i<=n;i++) p[i].Read();42 sort(p+1,p+n+1,cmp); makeblock();43 sort(p+1,p+n+1);44 for(int i=1;i<=n;i++)45 {46 if(p[i].x!=p[i-1].x) head=i;47 if(p[i].x!=p[i+1].x)48 {49 for(int j=head;j<=i;j++) insert(p[j]);50 for(int j=head;j<=i;j++) ++rank[query(p[j])-1];51 }52 }53 for(int i=0;i<n;i++) printf("%d\n",rank[i]);54 return 0;55 }
【三维偏序】【分块】bzoj3262 陌上花开
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。