题意的大体意思就是求N个矩形的面积并。可以算做是基础的模板题。
第一次用线段树写扫描线,感觉还不是很难。对于扫描线,选择扫描的方式很重要,第一次写的是从左往右扫,不知道是不是因为某处想到不周到还是因为其他的原因,总之一直在TLE,后来换成从上往下扫,跑了250MS,而且思路也清晰了许多。
#include <iostream> #include <cstring> #include <cstdlib> #include <cstdio> #include <queue> #include <cmath> #include <algorithm> #include <string> #define LL long long #define Max(a,b) (a) > (b) ? (a) : (b) #define Min(a,b) (a) < (b) ? (a) : (b) #define EPS (1e-8) #define Left 1 #define Right -1; using namespace std; struct L { LL l,r,h; }line[41000]; LL X[82000],area; bool cmp(LL a,LL b) { return a < b; } bool cmph(L l1,L l2) { return l1.h > l2.h; } LL delsame(LL *p,LL n) { if(n == 0) return 0; LL i,top; for(i = 1,top = 1;i < n; ++i) { if(p[i] != p[i-1]) p[top++] = p[i]; } return top; } LL bs(LL *p,LL n,LL m) { LL s = 0,e = n-1,mid; while(s < e) { mid = (s+e)>>1; if(p[mid] == m) return mid; if(m < p[mid]) e = mid-1; else s = mid+1; } mid = (s+e)>>1; if(p[mid] == m) return mid; return -1; } struct ST { LL l,r; bool mark,ls,rs; }st[324000]; void init_st(LL site,LL l,LL r) { if(l >= r) return; if(l == r-1) { st[site].l = l; st[site].r = r; st[site].mark = false; st[site].ls = false; st[site].rs = false; return ; } st[site].l = l; st[site].r = r; st[site].mark = false; st[site].ls = false; st[site].rs = false; LL mid = (l+r)>>1; init_st(site<<1,l,mid); init_st(site<<1|1,mid,r); } void Cal_Area(LL site,LL l,LL r,LL h) { if(l >= r || st[site].mark) return ; if(st[site].l == l && st[site].r == r) { if(st[site].ls == false && st[site].rs == false) { st[site].mark = true; area += h*(X[r]-X[l]); return ; } else { LL mid = (st[site].l+st[site].r)>>1; st[site].ls = true; st[site].rs = true; Cal_Area(site<<1,l,mid,h); Cal_Area(site<<1|1,mid,r,h); if(st[site].ls && st[site].rs && st[site<<1].mark && st[site<<1|1].mark) { st[site].mark = true; } } } LL mid = (st[site].l+st[site].r)>>1; if(r <= mid) { st[site].ls = true; Cal_Area(site<<1,l,r,h); if(st[site].ls && st[site].rs && st[site<<1].mark && st[site<<1|1].mark) { st[site].mark = true; } return ; } if(mid <= l) { st[site].rs = true; Cal_Area(site<<1|1,l,r,h); if(st[site].ls && st[site].rs && st[site<<1].mark && st[site<<1|1].mark) { st[site].mark = true; } return ; } st[site].ls = true; st[site].rs = true; Cal_Area(site<<1,l,mid,h); Cal_Area(site<<1|1,mid,r,h); if(st[site].ls && st[site].rs && st[site<<1].mark && st[site<<1|1].mark) { st[site].mark = true; } } int main() { LL i,n,top,s1,s2; while(scanf("%lld",&n) != EOF) { for(top = 0,i = 0;i < n; ++i) { scanf("%lld %lld %lld",&line[i].l,&line[i].r,&line[i].h); X[top++] = line[i].l; X[top++] = line[i].r; } sort(X,X+top,cmp); sort(line,line+n,cmph); top = delsame(X,top); init_st(1,0,top-1); for(area = 0,i = 0;i < n; ++i) { s1 = bs(X,top,line[i].l); s2 = bs(X,top,line[i].r); Cal_Area(1,s1,s2,line[i].h); } printf("%lld\n",area); } return 0; }