题意:求N个矩形中,求被覆盖至少俩次的面积和
分析:一开始以为用总面积减去面积并就可以了,可是想了想,当面积被覆盖了俩次以上,就漏减 了,所以只能老老实实算了。
具体方法跟求面积并十分类似,求面积并时,排完序之后,每次插入一条线段之后,求出整个区间当前被覆盖的总长度再乘以 前后俩条线段的水平距离;
而这道题目,每次插入一条线段之后,求整个区间当前被覆盖至少俩次的总长度再乘以水平距离,;
要求整个区间被覆盖至少俩次的总长度,只需在原有代码上添加几个更新而已,具体代码附了解释
#include#include #define maxn 2222using namespace std;struct node{ double x,y1,y2; int s; node(double a=0,double b=0,double c=0,int d=0):x(a),y1(b),y2(c),s(d){} friend bool operator<(const node a,const node b) { return a.x =2)//若被覆盖了俩次以上,则inlen[k]等于区间长度 inlen[k]=map1[t+1]-map1[s]; else if(t==s)//叶节点,等于零 inlen[k]=0; else if(cnt[k]==1)//若该区间整体被覆盖过一次,则inlen[k]等于子区间被覆盖过一次的线段长度之和 inlen[k]=len[k<<1]+len[k<<1|1]; else inlen[k]=inlen[k<<1]+inlen[k<<1 |1];//若整体没被标记过,则inlen[k]等于子区间被覆盖过俩次的线段长度之和}void update(int l,int r,int c,int s,int t,int k){ if(l<=s && t<=r) { cnt[k]+=c; PushUp(k,s,t); inPushUp(k,s,t); return ; } int kl=k<<1,kr=kl+1,mid=(s+t)>>1; if(l<=mid) update(l,r,c,s,mid,kl); if(r>mid) update(l,r,c,mid+1,t,kr); PushUp(k,s,t); inPushUp(k,s,t);}int Bin(double key,int n,double map1[]) { int l = 0 , r = n - 1; while (l <= r) { int mid = (l + r) >> 1; if (map1[mid] == key) return mid; if (map1[mid] < key) l = mid + 1; else r = mid - 1; } return -1;}int main(){ double a,b,c,d; int n,T; scanf("%d",&T); while(T--) { scanf("%d",&n); int m=0; for(int i=0;i