hdu3642 Get The Treasury
来源:互联网 发布:mac rar解压软件 编辑:程序博客网 时间:2024/06/05 23:51
题意:给一些长方体,求这些长方体相交2次以上的体积
思路:在做过两维的之后做这个其实是一样的思路,先把z(第三维)处理了,然后在各个平面上面做扫描线(这里就和两维的一样了)
#include<stdio.h>#include<string.h>#include<vector>#include<algorithm>#define LL __int64using namespace std;const int maxn = 1010;struct haha{int x1,x2,y1,y2,z1,z2;}s[maxn]; ///保存输入struct node{ int x,y1,y2,f; node(){} node(int xx,int yy1,int yy2,int ff) {x=xx,y1=yy1,y2=yy2,f=ff;} bool operator<(node a)const { if(x==a.x) return f < a.f; return x < a.x; }}sa[maxn*2];int Y[maxn*2],Z[maxn*2]; ///离散化坐标Y,Zint T,n,y,z; bool has[maxn]; ///表示这个长方体还在不在计算范围vector<pair<int,int> >pp[maxn*2]; ///表示各个长方体插入或删除int cov[maxn<<3],one[maxn<<3],two[maxn<<3],more[maxn<<3]; ///cov表示当前段覆盖,one,two,more表示覆盖1次,2次,多次void pushup(int rt,int l,int r){ int ls = rt<<1,rs = rt<<1|1; if(l==r) ls = 0,rs = 0; ///也可以再把数组开大2倍 if(cov[rt]==0) { more[rt] = more[ls] + more[rs]; two[rt] = two[ls] + two[rs]; one[rt] = one[ls] + one[rs]; } if(cov[rt]==1) { more[rt] = two[ls] + two[rs] + more[ls] + more[rs]; two[rt] = one[ls] + one[rs]; one[rt] = Y[r+1] - Y[l] - two[rt] - more[rt]; } if(cov[rt]==2) { more[rt] = one[ls] + one[rs] + two[ls] + two[rs] + more[ls] + more[rs]; two[rt] = Y[r+1] - Y[l] - more[rt]; one[rt] = 0; } if(cov[rt]==3) { more[rt] = Y[r+1] - Y[l]; one[rt] = two[rt] = 0; }}void update(int L,int R,int x,int l,int r,int rt){ if(L<=l&&r<=R) { cov[rt]+=x; pushup(rt,l,r); return; } int m = (l+r)/2; if(L<=m) update(L,R,x,l,m,rt<<1); if(R>m) update(L,R,x,m+1,r,rt<<1|1); pushup(rt,l,r);}LL calc() ///扫描当前平面{ LL res = 0; int en = 0; for(int i=0;i<n;i++) if(has[i]) { int y1 = lower_bound(Y,Y+y,s[i].y1)-Y; int y2 = lower_bound(Y,Y+y,s[i].y2)-Y-1; sa[en++] = node(s[i].x1,y1,y2,1); sa[en++] = node(s[i].x2,y1,y2,-1); } sort(sa,sa+en); memset(cov,0,sizeof(cov)); memset(one,0,sizeof(one)); memset(two,0,sizeof(two)); memset(more,0,sizeof(more)); for(int i=0;i<en-1;i++) { update(sa[i].y1,sa[i].y2,sa[i].f,0,y,1); res += (LL)more[1]*(sa[i+1].x - sa[i].x); } return res;}int main(){ scanf("%d",&T); for(int ca=1;ca<=T;ca++) { scanf("%d",&n); for(int i=0;i<n;i++) { scanf("%d%d%d%d%d%d",&s[i].x1,&s[i].y1,&s[i].z1,&s[i].x2,&s[i].y2,&s[i].z2); Y[i] = s[i].y1, Y[i+n] = s[i].y2; Z[i] = s[i].z1, Z[i+n] = s[i].z2; pp[i].clear(), pp[i+n].clear(); has[i] = 0; } sort(Z, Z+2*n); z = unique(Z, Z+2*n) - Z; sort(Y, Y+2*n); y = unique(Y, Y+2*n) - Y; for(int i=0;i<n;i++) { int t1 = lower_bound(Z, Z+z, s[i].z1)-Z; int t2 = lower_bound(Z, Z+z, s[i].z2)-Z; pp[t1].push_back(make_pair(i,1)); pp[t2].push_back(make_pair(i,-1)); } LL ans = 0; for(int i=0;i<z-1;i++) ///分开z个平面来分别做扫描线 { for(int j=0;j<pp[i].size();j++) { if(pp[i][j].second>0) has[pp[i][j].first]=1; else has[pp[i][j].first]=0; } ans += calc()*(Z[i+1]-Z[i]); } printf("Case %d: %I64d\n", ca, ans); } return 0;}
0 0
- hdu3642 Get The Treasury
- 线段树 hdu3642 Get The Treasury
- hdu3642 Get The Treasury--线段树 & 扫描线 & 面积并(待解决)
- 【hdu3642】Get The Treasury (立方体体积交+线段树+扫描线)
- hdu3642-Get The Treasury 线段树+扫描线+离散化 求三维体积并
- 扫描线 n个立方体相交区域大于等于三次的体积和 hdu3642 Get The Treasury
- hdu 3642 Get The Treasury
- HDU 3642 Get The Treasury
- HDU-3642-Get The Treasury
- HDU 3642 Get The Treasury
- HDU_3642 Get The Treasury 线段树
- hdu 3642 Get The Treasury(扫描线)
- hdu 3642 Get The Treasury(线段树求体积并)
- hdu 3642 Get The Treasury (三维的扫描线)
- hdu-3642--Get The Treasury-线段树求面积并
- hdu 3642 Get The Treasury(扫描线、立方体交)
- HDU 3642 Get The Treasury(线段树)
- Hdu 3642 Get The Treasury(长方体的体积交)
- $Proxy11 cannot be cast to cn.oa.service.impl.UserServiceImpl
- VNC远程登录树莓派的图形界面
- Python yield 用法
- android socket编程client
- thinkpython 练习题4.3
- hdu3642 Get The Treasury
- Oracle结构化查询语言(Structured Query Language)
- Web framework之Mybatis3
- golang udp
- 杭电 HDU ACM 1330 Deck
- 10
- Hiberate之数据对象关联关系
- ORACLE_基础九(Tables)
- 【学习笔记】Navigation