typedef struct x { int left; int right; int cov; int len; }Tree; typedef struct Linex { int x1; int x2; int y; int flag; }Line; const int MAX=50050; int linenum,n; Tree tree[MAX*4]; Line line[MAX*2]; bool cmp(Line a,Line b) {return a.y<b.y;} void BuildTree(int left,int right,int i)//左右两个区间有重叠的部分 { tree[i].left=left; tree[i].right=right; tree[i].cov=tree[i].len=0; if(left+1==right)return ; int mid=(left+right)>>1; BuildTree(left,mid,i<<1); BuildTree(mid,right,2*i+1); } void clear(int i) { if(tree[i].cov==0) tree[i].len=tree[i<<1].len+tree[2*i+1].len; } void updata(int left,int right,int flag,int i) { if(left<=tree[i].left&&right>=tree[i].right) { if(flag==1)//如果是入边,覆盖+1 { tree[i].cov++; tree[i].len=tree[i].right-tree[i].left; } else//当线段被删除之后,子线段可能还存在 { tree[i].cov--; if(tree[i].cov==0) { if(tree[i].left+1==tree[i].right) tree[i].len=0; else tree[i].len=tree[i<<1].len+tree[2*i+1].len; } } return ; } if(left<tree[i<<1].right)updata(left,right,flag,i<<1); if(right>tree[i<<1|1].left)updata(left,right,flag,i<<1|1); clear(i); } void addline(int x1,int y1,int x2,int y2)//每个矩阵,记录两条线段 { if(x1==x2||y1==y2)return ;//如果矩阵不合法 line[linenum].x1=x1; line[linenum].x2=x2; line[linenum].y=y1; line[linenum].flag=1; linenum++; line[linenum].x1=x1; line[linenum].x2=x2; line[linenum].y=y2; line[linenum].flag=-1; linenum++; }
sort(line,line+linenum,cmp); BuildTree(0,MAX,1); updata(line[0].x1,line[0].x2,line[0].flag,1); __int64 ans=0; for(i=1;i<linenum;i++) { ans+=(__int64)tree[1].len*(line[i].y-line[i-1].y); updata(line[i].x1,line[i].x2,line[i].flag,1); } printf("%I64d\n",ans);
线段树 扫描线求矩阵面积并的模板(zz)
最新推荐文章于 2020-08-08 11:12:40 发布