zoukankan      html  css  js  c++  java
  • HDU1255 覆盖的面积(线段树+扫描线)

    对于覆盖的一次的,我们维护一格变量,对于覆盖两次的,我们维护两个变量,分别是s1,s2,覆盖一次以上和覆盖两次以上。

    通过这样的操作就可以直接根据儿子信息更新而不用维护一格pushdown操作

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<vector>
    #include<algorithm>
    using namespace std;
    typedef long long ll;
    const int N=3e5+10;
    const int mod=1e9+7;
    struct node{
        int l,r,lazy;
        double s1,s2;
    }tr[N];
    vector<double> num;
    struct qi{
        double x;
        double y,y2;
        int k;
        bool operator <(const qi& t) const{
            return x<t.x;
        }
    }sg[N];
    int find(double x){
        return lower_bound(num.begin(),num.end(),x)-num.begin()+1;
    }
    void build(int u,int l,int r){
        if(l==r){
            tr[u]=node{l,l,0,0,0};
        }
        else{
            tr[u]=node{l,r,0,0,0};
            int mid=l+r>>1;
            build(u<<1,l,mid);
            build(u<<1|1,mid+1,r);
        }
    }
    void pushup(int u){
        if(tr[u].lazy>=2){
            tr[u].s2=num[tr[u].r]-num[tr[u].l-1];
            tr[u].s1 =num[tr[u].r]-num[tr[u].l-1];
        }
        else if(tr[u].lazy==1){
            tr[u].s2=tr[u<<1].s1+tr[u<<1|1].s1;
            tr[u].s1 =num[tr[u].r]-num[tr[u].l-1];
        }
        else{
            if(tr[u].l==tr[u].r)
                tr[u].s2 = tr[u].s1 = 0;
            else{
                tr[u].s2= tr[u<<1].s2+tr[u<<1|1].s2;
                tr[u].s1 = tr[u<<1].s1+tr[u<<1|1].s1;
            }
        }
    }
    void modify(int u,int l,int r,int x){
        if(tr[u].l>=l&&tr[u].r<=r){
            tr[u].lazy+=x;
            pushup(u);
            return ;
        }
        int mid=tr[u].l+tr[u].r>>1;
        if(l<=mid)
            modify(u<<1,l,r,x);
        if(r>mid)
            modify(u<<1|1,l,r,x);
        pushup(u);
    }
    int main(){
        int n;
        int t;
        cin>>t;
        while(t--){
            cin>>n;
            num.clear();
            int i;
            double x1,x2,y,y2;
            int cnt=1;
            for(i=1;i<=n;i++){
                   scanf("%lf%lf%lf%lf",&x1,&y,&x2,&y2);
                   sg[cnt++]={x1,y,y2,1};
                   sg[cnt++]={x2,y,y2,-1};
                num.push_back(y);
                num.push_back(y2);
            }
            sort(sg+1,sg+1+2*n);
            sort(num.begin(),num.end());
            num.erase(unique(num.begin(),num.end()),num.end());
            build(1,1,num.size()-1);
            double sum=0;
            for(i=1;i<=2*n;i++){
                if(i>1){
                    sum+=tr[1].s2*(sg[i].x-sg[i-1].x);
                }
                modify(1,find(sg[i].y),find(sg[i].y2)-1,sg[i].k);
            }
            printf("%.2f
    ",sum);
        }
        return 0;
    }
    View Code
  • 相关阅读:
    常用的学生、课程、成绩、教师表的查询
    flutter 自定义TabBar
    Flutter 设置input边框
    Flutter ReorderableListView 可拖拽的列表
    Flutter NotificationListener 监听列表的滚动
    Flutter 使用Tabbar不要Title
    Nestjs 验证对象数组
    postman 发送数组
    JS面向切面编程AOP
    什么是匿名函数、什么是闭包函数?
  • 原文地址:https://www.cnblogs.com/ctyakwf/p/12871872.html
Copyright © 2011-2022 走看看