• 覆盖的面积 HDU


    #include<bits/stdc++.h>
    using namespace std;
    #define ll long long
    
    const int maxn=1010;
    
    int n;
    double X[maxn<<1];
    
    struct Edge{
    	double l,r,h;
    	int v;
    	Edge(){};
    	Edge(double a,double b,double c,int d):l(a),r(b),h(c),v(d){};
    	bool operator<(const Edge &b)const{
    		if(h==b.h)return v>b.v;
    		return h<b.h;
    	}
    }edge[maxn<<1];
    
    struct node{
    	int l,r,cnt;
    	double s,ss;
    }ST[maxn<<3];
    
    void build(int l,int r,int rt){
    	ST[rt].l=l;ST[rt].r=r;
    	ST[rt].cnt=ST[rt].s=ST[rt].ss=0;
    	if(l==r)return;
    	int m=l+r>>1;
    	build(l,m,rt<<1);
    	build(m+1,r,rt<<1|1);
    }
    
    void cal(int l,int r,int rt){
    	if(ST[rt].cnt){
    		ST[rt].s=X[r+1]-X[l];
    	}else if(ST[rt].l==ST[rt].r){
    		ST[rt].s=0;
    	}else{
    		ST[rt].s=ST[rt<<1].s+ST[rt<<1|1].s;
    	}
    	///
    	if(ST[rt].cnt>1){
    		ST[rt].ss=X[r+1]-X[l];
    	}else if(l==r){
    		ST[rt].ss=0;
    	}else if(ST[rt].cnt==1){
    		ST[rt].ss=ST[rt<<1].s+ST[rt<<1|1].s;
    	}else{
    		ST[rt].ss=ST[rt<<1].ss+ST[rt<<1|1].ss;
    	}
    }
    
    void update(int a,int b,int v,int l,int r,int rt){
    	if(a<=l&&b>=r){
    		ST[rt].cnt+=v;
    		cal(l,r,rt);
    		return;
    	}
    	int m=l+r>>1;
    	if(a<=m)update(a,b,v,l,m,rt<<1);
    	if(b>m)update(a,b,v,m+1,r,rt<<1|1);
    	cal(l,r,rt);
    }
    
    int main(){
    	int T;
    	scanf("%d",&T);
    	while(T--){
    		scanf("%d",&n);
    		int tt=0;
    		for(int i=1;i<=n;i++){
    			double x1,x2,y1,y2;
    			scanf("%lf %lf %lf %lf",&x1,&y1,&x2,&y2);
    			X[++tt]=x1;
    			edge[tt]=Edge(x1,x2,y1,1);
    			X[++tt]=x2;
    			edge[tt]=Edge(x1,x2,y2,-1);
    		}
    		sort(X+1,X+tt+1);
    		sort(edge+1,edge+tt+1);
    		int m=1;
    		for(int i=2;i<=tt;i++){
    			if(X[i]!=X[i-1])X[++m]=X[i];
    		}
    		build(1,m,1);
    
    		double ans=0;
    		for(int i=1;i<tt;i++){
    			int l=lower_bound(X+1,X+m+1,edge[i].l)-X;
    			int r=lower_bound(X+1,X+m+1,edge[i].r)-X-1;
    			update(l,r,edge[i].v,1,m,1);
    			ans+=ST[1].ss*(edge[i+1].h-edge[i].h);
    
    		}
    		printf("%.2lf
    ",ans);
    	}
    }

    大部分代码风格能和扫描线保持一致还蛮开心的。。

    多次覆盖的核心就在于cal函数

    若当前区间被覆盖过一次,当前区间被覆盖2次的长度就加上子节点们覆盖1次的长度

    当时听学长讲的时候还感觉很迷,当时光听,没分清楚覆盖次数和覆盖长度。。orz

    估计判AC的时候给了eps吧。。不然我样例都没过啊(

  • 相关阅读:
    python10.31
    python10.29
    python10.28
    python10.27
    python10.25
    python10.24
    python10.23
    四边形不等式与决策单调
    0x57~0x59
    0x55~0x56
  • 原文地址:https://www.cnblogs.com/Drenight/p/8611320.html
Copyright © 2020-2023  润新知