线段树扫描线

大佬的博客

看了好几天,感觉自己看懂了。

https://blog.csdn.net/riba2534/article/details/76851233这个大佬内部有图,可以手动纸上跟着画一下加深理解

扫描线可以水平扫,也可以垂直扫,这里我说一下垂直扫吧。

题目给出的坐标为浮点数,那么我们将所有的y坐标排序离散化后,假设共有m个不同的坐标值,设为val[1~m]。

那么这m个不同的y值就可以将一条垂直x轴的直线划分为m-1段吧(超出最大的y,与小于最小的y的地方不算),

线段树扫描线_第1张图片

那么为这m-1个线段标号分别为1~m-1,线段树维护的就是这m-1根线段被覆盖了多少次。

就比如节点[1,1]就表示的是线段1,长度为val[2]-val[1]。[2,5]就表示的是从2~5包含的所有线段,长度为val[6]-val[2]。

将每个矩形拆成两个四元组 (x1,y1,y2,1) (x2,y1,y2,-1) 按照x从小到大排序逐次将2*n-1条加入线段树(不加入最后一条)

线段树中的每个节点都表示不同的含义,不同于普通的线段树需要将子树的信息更新到叶子节点。

不下传标记

 

一道裸题:https://www.acwing.com/problem/content/249/

#include
using namespace std;

const int maxn=209;

double y[maxn];


int cnt[maxn<<2|1];
double len[maxn<<2|1];
int m;
struct Node{
    double y1,y2,h;
    int v;
    bool operator <(const Node& x)const{
        return h=L&&r<=R){
        cnt[k]+=v;
        pushup(l,r,k);
        return ;
    }
    int mid=(l+r)>>1;
    if(L<=mid) updata(L,R,l,mid,k<<1,v);
    if(R>mid) updata(L,R,mid+1,r,k<<1|1,v);
    pushup(l,r,k);

}
void prin(){
    for(int i=1;i<=20;++i) cout<

这位大佬有讲面积交:https://www.cnblogs.com/lxjshuju/p/7040186.html

#include
using namespace std;
typedef long long ll;

const int maxn=2009;
double y[maxn];
int m;
void quchong(int n){
    sort(y+1,y+1+n);
    m=unique(y+1,y+1+n)-(y+1);
}

int getid(double x){
    return lower_bound(y+1,y+1+m,x)-(y+1)+1;
}

struct Node{
    double h,y1,y2;
    int v;
    bool operator <(const Node& x)const{
        return h=2) len2[k]=y[r+1]-y[l];
    else if(l==r) len2[k]=0;
    else if(cnt[k]==1) len2[k]=len1[k<<1]+len1[k<<1|1];
    else len2[k]=len2[k<<1]+len2[k<<1|1];
}

void updata(int L,int R,int l,int r,int k,int v){
    if(l>=L&&r<=R){
        cnt[k]+=v;
        pushup(l,r,k);
        return ;
    }
    int mid=(l+r)>>1;
    if(L<=mid) updata(L,R,l,mid,k<<1,v);
    if(R>mid) updata(L,R,mid+1,r,k<<1|1,v);
    pushup(l,r,k);
}

int main(){
    int t;
    scanf("%d",&t);
    int n;
    double x1,x2,y1,y2;
    while(t--){
        build();
        scanf("%d",&n);
        for(int i=1;i<=n;++i){
            scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2);
            int k=(i<<1);
            a[k-1].h=x1,a[k-1].y1=y1,a[k-1].y2=y2,a[k-1].v=1;
            a[k].h=x2,a[k].y1=y1,a[k].y2=y2,a[k].v=-1;
            y[k-1]=y1,y[k]=y2;
        }
        double res=0;
        n<<=1;
        sort(a+1,a+1+n);
        quchong(n);

        for(int i=1;i

 

你可能感兴趣的:(线段树)