下面资料 均为网上收集
给定一个矩形的左下角坐标和右上角坐标分别为:(x1,y1)、(x2,y2),对这样的一个矩形,我们构造两条线段,一条定位在x1,它在y坐标的区间是[y1,y2],并且给定一个cover域值为1;另一条线段定位在x2,区间一样是[y1,y2],给定它一个cover值为-1。根据这样的方法对每个矩形都构造两个线段,最后将所有的线段根据所定位的x从左到右进行排序。
上图中,红色的字体表示的是该线段的cover值。刚刚开始的时候,线段树上的cover值都为0,但第一根线段(x==0)插入线段树的之后,我们将线段树上的cover加上该线段的cover,那么,此时线段树上被该线段覆盖的位置上的cover的值就为1,下次再插入第二根线段(x==1)此时发现该线段所覆盖的区间内,有一部分线段树的cover为0,另有一部分为1,仔细观察,但插入第二个线段的时候,如果线段树上cover已经为1的那些区间,和现在要插入的第二根线段之间,是不是构成了并面积?还不明白?看下图,绿色部分即为插入第二根线段后得到的并面积
够清楚了吧!也就是说,我们插入某跟线段的时候,只要看该线段所在区间上的cover是否大于等于1,如果是,那么就可以将并面积值加上(目前线段的x定位 - 上一线段的x定位)*(该区间的大小)
经典的矩形面积并;线段树保存当前线段的总长度
1。对x轴建树,将矩形分成下边+上边+高;
2.按y升序排序
3.y从低到高{
if(遇到下边)就将长度为x.r-x.l的线段插入线段树(该区间的覆盖次数加1)
else(遇到上边)就将长度为x.r-x.l的从线段树中删除(该区间的覆盖次数减1)
同时计算当前面积,即线段长度和l*h(当前线段与下一条线段的高度差)
}
注意本题是一遍添加 一边释放 不会造成面积的重复计算
今天下午一直昏昏沉沉,提不起精神,勉强做了这个题,希望是个转折吧
#include "stdio.h"
#include "algorithm"
using namespace std;
struct {
<wbr><wbr><wbr> int l,r;<br><wbr><wbr><wbr> int cnt;<br><wbr><wbr><wbr> double sum;<br><wbr><wbr><wbr> int getmid(){<br><wbr><wbr><wbr><wbr><wbr><wbr> return (l+r)/2;<br><wbr><wbr><wbr> }<br> }st[6666];//横线段的线段树<br><br> struct SS{<br><wbr><wbr><wbr> double l,r;<br><wbr><wbr><wbr> double h;<br><wbr><wbr><wbr> int s;<br> }ss[6666];//横线段<br> double pos[6666];//横坐标<br> int k;//横坐标的个数<br> int bin(int c);<br> bool cmp(struct SS&a,struct SS&b){<br><wbr><wbr><wbr> return a.h<b.h;<span><span class="comment">//从小到大</span><span></span></span><br> }<br><br> void build(int a,int b,int ind){<br><wbr><wbr><wbr> st[ind].l=a;<br><wbr><wbr><wbr> st[ind].r=b;<br><wbr><wbr><wbr> st[ind].cnt=0;<br><wbr><wbr><wbr> st[ind].sum=0;<br><wbr><wbr><wbr> if(a==b)<br><wbr><wbr><wbr><wbr><wbr><wbr> return ;<br><wbr><wbr><wbr> int mid=st[ind].getmid();<br><wbr><wbr><wbr> build(a,mid,ind*2);<br><wbr><wbr><wbr> build(mid+1,b,ind*2+1);<br> }<br> void update(int ind){<br><wbr><wbr><wbr> if(st[ind].cnt){<br><wbr><wbr><wbr><wbr><wbr><wbr> st[ind].sum=pos[st[ind].r+1]-pos[st[ind].l];//在计算和时,还原点值,所以+1<br><wbr><wbr><wbr> }else if(st[ind].l==st[ind].r){<br><wbr><wbr><wbr><wbr><wbr><wbr> st[ind].sum=0;<br><wbr><wbr><wbr> }<br><wbr><wbr><wbr> else{<br><wbr><wbr><wbr><wbr><wbr><wbr> st[ind].sum=st[ind*2].sum+st[ind*2+1].sum;<br><wbr><wbr><wbr> }<br> }<br> void insert(int a,int b,int c,int ind){<br><wbr><wbr><wbr> if(a<=st[ind].l&&st[ind].r<=b){<br><wbr><wbr><wbr><wbr><wbr><wbr> st[ind].cnt+=c;<br><wbr><wbr><wbr> }else{<br><wbr><wbr><wbr><wbr><wbr><wbr> int mid=st[ind].getmid();<br><wbr><wbr><wbr><wbr><wbr><wbr> if(a<=mid)<br><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr> insert(a,b,c,ind*2);<br><wbr><wbr><wbr><wbr><wbr><wbr> if(b>mid)<br><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr> insert(a,b,c,ind*2+1);<br><wbr><wbr><wbr> }<br><wbr><wbr><wbr> update(ind);<br> }<br> int bin(double c){<br><wbr><wbr><wbr> int p,q;<br><wbr><wbr><wbr> p=0;<br><wbr><wbr><wbr> q=k-1;<br><wbr><wbr><wbr> while(p<=q){<br><wbr><wbr><wbr><wbr><wbr><wbr> int mid=(p+q)/2;<br><wbr><wbr><wbr><wbr><wbr><wbr> if(pos[mid]==c)<br><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr> return mid;<br><wbr><wbr><wbr><wbr><wbr><wbr> if(pos[mid]<c)<br><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr> p=mid+1;<br><wbr><wbr><wbr><wbr><wbr><wbr> else<br><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr> q=mid-1;<br><wbr><wbr><wbr> }<br><wbr><wbr><wbr> return -1;<br> }<br> int main(){<br><wbr><wbr><wbr> int n,m;<br><wbr><wbr><wbr> double x1,x2;<br><wbr><wbr><wbr> int cx=-1;<br><wbr><wbr><wbr> for(;;){<br><wbr><wbr><wbr><wbr><wbr><wbr> scanf("%d",&n);<br><wbr><wbr><wbr><wbr><wbr><wbr> if(n==0)<br><wbr><wbr><wbr><wbr><wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr>