线段树+扫描线+离散化,算是比较经典的题目吧,我自己做的时候不会做,百度的题解。。。发现不需要用pushdown,只用pushup就可以解决。。。pushup的代码如下
void pushup(int o, int L, int R) { if(cover[o]==0){ once[o]=once[o<<1]+once[o<<1 | 1]; more[o]=more[o<<1]+more[o<<1 | 1]; } if(cover[o]==1){ once[o]=x[R+1]-x[L]; more[o]=once[o<<1]+once[o<<1 | 1]; } if(cover[o]==2) once[o]=more[o]=x[R+1]-x[L]; }
其他的部分都不难。。。
#include <iostream> #include <sstream> #include <algorithm> #include <vector> #include <queue> #include <stack> #include <map> #include <set> #include <bitset> #include <cstdio> #include <cstring> #include <cstdlib> #include <cmath> #include <climits> #define maxn 10005 #define eps 1e-6 #define mod 200000007 #define INF 99999999 #define lowbit(x) (x&(-x)) #define lson o<<1, L, mid #define rson o<<1 | 1, mid+1, R typedef long long LL; using namespace std; double x[maxn]; double once[maxn]; double more[maxn]; int cover[maxn]; int xcnt; struct segment { double x1, x2, h; int flag; }seg[maxn]; int ql, qr, k; int n, m; double ans; int cmp1(double a, double b) { return a<b; } int cmp2(segment a, segment b) { return a.h<b.h; } int search(double tmp) { int bot=1, top=xcnt, mid; while(top>=bot){ mid=(bot+top)>>1; if(abs(x[mid]-tmp)<eps) break; if(x[mid]>tmp) top=mid-1; else bot=mid+1; } return mid; } void read(void) { int i, j; scanf("%d",&n); xcnt=1; for(i=0, j=0;i<n;i++){ scanf("%lf%lf", &seg[j].x1, &seg[j].h); scanf("%lf%lf", &seg[j+1].x2, &seg[j+1].h); seg[j].flag=1, seg[j+1].flag=-1; seg[j].x2=seg[j+1].x2, seg[j+1].x1=seg[j].x1; x[xcnt++]=seg[j].x1, x[xcnt++]=seg[j].x2, j+=2; } xcnt--, m=j; sort(x+1, x+xcnt+1, cmp1); for(i=2, j=2;i<=xcnt;i++) if(abs(x[i]-x[i-1])>eps) x[j++]=x[i]; xcnt=j-1; sort(seg, seg+m, cmp2); } void init(void) { memset(once, 0, sizeof once); memset(more, 0, sizeof more); memset(cover, 0, sizeof cover); } void pushup(int o, int L, int R) { if(cover[o]==0){ once[o]=once[o<<1]+once[o<<1 | 1]; more[o]=more[o<<1]+more[o<<1 | 1]; } if(cover[o]==1){ once[o]=x[R+1]-x[L]; more[o]=once[o<<1]+once[o<<1 | 1]; } if(cover[o]==2) once[o]=more[o]=x[R+1]-x[L]; } void updata(int o, int L, int R) { if(ql<=L && qr>=R){ cover[o]+=k; pushup(o, L, R); return; } int mid=(R+L)>>1; if(ql<=mid) updata(lson); if(qr>mid) updata(rson); pushup(o, L, R); } void work(void) { double tmp=0; double res=0; ql=search(seg[0].x1), qr=search(seg[0].x2)-1; k=seg[0].flag; updata(1, 1, xcnt-1); for(int i=1;i<m;i++){ ql=search(seg[i].x1), qr=search(seg[i].x2)-1; k=seg[i].flag; res+=more[1]*(seg[i].h-tmp); tmp=seg[i].h; updata(1, 1, xcnt-1); } printf("%.2f\n", res); } int main(void) { int _; while(scanf("%d",&_)!=EOF){ while(_--){ init(); read(); work(); } } return 0; }