标签:线段树
2 5 1 1 4 2 1 3 3 7 2 1.5 5 4.5 3.5 1.25 7.5 4 6 3 10 7 3 0 0 1 1 1 0 2 1 2 0 3 1
7.63 0.00
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<cmath> #include<queue> #include<stack> #include<vector> #include<set> #include<map> #define L(x) (x<<1) #define R(x) (x<<1|1) #define MID(x,y) ((x+y)>>1) #define eps 1e-8 #define ll long long #define fre(i,a,b) for(i = a; i <b; i++) #define free(i,b,a) for(i = b; i >= a;i--) #define mem(t, v) memset ((t) , v, sizeof(t)) #define ssf(n) scanf("%s", n) #define sf(n) scanf("%d", &n) #define sff(a,b) scanf("%d %d", &a, &b) #define sfff(a,b,c) scanf("%d %d %d", &a, &b, &c) #define pf printf #define bug pf("Hi\n") using namespace std; #define INF 0x3f3f3f3f #define N 10005 struct stud{ double x1,x2,h; int type; bool operator <(const stud b) const { return h<b.h; } }e[N]; struct studd{ int le,ri; int cover; double once,len; }f[N]; map<double,int>mp; double x[N]; void build(int pos,int le,int ri) { f[pos].le=le; f[pos].ri=ri; f[pos].cover=0; f[pos].once=f[pos].len=0; if(le+1==ri) return ; int mid=MID(le,ri); build(L(pos),le,mid); build(R(pos),mid,ri); } void pushup(int pos) { if(f[pos].cover>=2) { f[pos].len=x[f[pos].ri]-x[f[pos].le]; f[pos].once=0; return ; } if(f[pos].cover==1) //这个区间被覆盖一次,那么两次的应该是下面的两次的加下面的一次的 { if(f[pos].le+1==f[pos].ri) { f[pos].len=0; f[pos].once=x[f[pos].ri]-x[f[pos].le]; } else { f[pos].len=f[L(pos)].len+f[L(pos)].once+f[R(pos)].len+f[R(pos)].once; f[pos].once=x[f[pos].ri]-x[f[pos].le]-f[pos].len; } return ; } if(f[pos].le+1==f[pos].ri) { f[pos].len=f[pos].once=0; } else { f[pos].len=f[L(pos)].len+f[R(pos)].len; f[pos].once=f[L(pos)].once+f[R(pos)].once; } } void update(int pos,int le,int ri,int type) { if(f[pos].le>=le&&f[pos].ri<=ri) { f[pos].cover+=type; pushup(pos); return ; } int mid=MID(f[pos].le,f[pos].ri); if(mid>le) update(L(pos),le,ri,type); if(mid<ri) update(R(pos),le,ri,type); pushup(pos); } int main() { int i,j,n,k,t; double x1,x2,y1,y2; sf(t); while(t--) { sf(n); k=0; fre(i,0,n) { scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2); if(x1>x2) swap(x1,x2); x[k]=x1; e[k].x1=x1; e[k].x2=x2; e[k].h=y1; e[k++].type=1; x[k]=x2; e[k].x1=x1; e[k].x2=x2; e[k].h=y2; e[k++].type=-1; } sort(x,x+k); sort(e,e+k); n=unique(x,x+k)-x; fre(i,0,n) mp[x[i]]=i; n--; build(1,0,n); double ans=0; fre(i,0,k-1) { int le=mp[e[i].x1]; int ri=mp[e[i].x2]; update(1,le,ri,e[i].type); ans+=f[1].len*(e[i+1].h-e[i].h); } pf("%.2f\n",ans); } return 0; }
标签:线段树
原文地址:http://blog.csdn.net/u014737310/article/details/44748605