其他分享
首页 > 其他分享> > 【学习笔记/模板】扫描线 周长并

【学习笔记/模板】扫描线 周长并

作者:互联网

先开坑,晚上再写。

P1856 [IOI1998] [USACO5.5] 矩形周长Picture

Code

#include<cstdio>
#include<algorithm>

using namespace std;

const int MAXN = 1e5 + 10;
int n, tot_x, tot_y, last_x, last_y;
long long sum;
int val_x[MAXN], val_y[MAXN];
int x[MAXN], y[MAXN]; //离散化用临时数组

struct Line{
    int s; 
    int l, r;
    int sit;
}line_x[MAXN << 1], line_y[MAXN << 1];

inline bool cmp(const Line &a, const Line &b){
    if(a.s == b.s)
        return a.sit > b.sit;
    return a.s < b.s;
}

struct Segment_Tree{
    struct Tree{
        int l, r;
        int len;
        int cnt; //被整体覆盖了几次 
    }tr[MAXN << 2];

    inline int lson(int rt){
        return rt << 1;
    }

    inline int rson(int rt){
        return rt << 1 | 1;
    }

    inline void Pushup(int rt, int *val){
        if(tr[rt].cnt)
            tr[rt].len = val[tr[rt].r + 1] - val[tr[rt].l];
        else
            tr[rt].len = tr[lson(rt)].len + tr[rson(rt)].len;
    }

    void Build(int rt, int l, int r){
        tr[rt].l = l;
        tr[rt].r = r;
        tr[rt].len = 0;
        tr[rt].cnt = 0;

        if(l == r)
            return;

        int mid = (l + r) >> 1;
        Build(lson(rt), l, mid);
        Build(rson(rt), mid + 1, r);
    }

    void Update(int rt, int l, int r, int data, int *val){
        if(tr[rt].l >= l && tr[rt].r <= r){
            tr[rt].cnt += data;
            Pushup(rt, val);

            return;
        }

        int mid = (tr[rt].l + tr[rt].r) >> 1;
        if(l <= mid) Update(lson(rt), l, r, data, val);
        if(r > mid) Update(rson(rt), l, r, data, val);

        Pushup(rt, val);
    }
}S_x, S_y;

inline int read(){
    int x = 0, f = 1;
    char c = getchar();

    while(c < '0' || c > '9'){
        if(c == '-') f = -1;
        c = getchar();
    }
    while(c >= '0' && c <= '9'){
        x = (x << 1) + (x << 3) + (c ^ 48);
        c = getchar();
    }

    return x * f;
}

int main(){
    n = read();
    for(register int i = 1; i <= n; i++){
        int x1, y1, x2, y2;
        x1 = read(), y1 = read(), x2 = read(), y2 = read();

        //line_x存横边 
        line_x[(i << 1) - 1].s = y1, line_x[(i << 1)].s = y2;
        line_x[(i << 1) - 1].l = line_x[(i << 1)].l = x1;
        line_x[(i << 1) - 1].r = line_x[(i << 1)].r = x2;
        line_x[(i << 1) - 1].sit = 1; 
        line_x[(i << 1)].sit = -1; 
        x[++tot_x] = x1;
        x[++tot_x] = x2;
        //line_y存竖边
        line_y[(i << 1) - 1].s = x1, line_y[(i << 1)].s = x2;
        line_y[(i << 1) - 1].l = line_y[(i << 1)].l = y1;
        line_y[(i << 1) - 1].r = line_y[(i << 1)].r = y2;
        line_y[(i << 1) - 1].sit = 1; 
        line_y[(i << 1)].sit = -1;
        y[++tot_y] = y1;
        y[++tot_y] = y2;
    }

    n <<= 1; 
    sort(x + 1, x + 1 + tot_x);
    sort(y + 1, y + 1 + tot_y);
    int cnt_x = unique(x + 1, x + 1 + tot_x) - x - 1;
    int cnt_y = unique(y + 1, y + 1 + tot_y) - y - 1;
    for(register int i = 1; i <= n; i++){
        int pos_x1 = lower_bound(x + 1, x + 1 + cnt_x, line_x[i].l) - x;
        int pos_x2 = lower_bound(x + 1, x + 1 + cnt_x, line_x[i].r) - x;
        int pos_y1 = lower_bound(y + 1, y + 1 + cnt_y, line_y[i].l) - y;
        int pos_y2 = lower_bound(y + 1, y + 1 + cnt_y, line_y[i].r) - y;

        val_x[pos_x1] = line_x[i].l;
        val_x[pos_x2] = line_x[i].r;
        line_x[i].l = pos_x1;
        line_x[i].r = pos_x2;

        val_y[pos_y1] = line_y[i].l;
        val_y[pos_y2] = line_y[i].r;
        line_y[i].l = pos_y1;
        line_y[i].r = pos_y2;
    }

    sort(line_x + 1, line_x + 1 + n, cmp);
    sort(line_y + 1, line_y + 1 + n, cmp);
    S_x.Build(1, 1, n);
    S_y.Build(1, 1, n);

    for(register int i = 1; i <= n; i++){
        S_x.Update(1, line_x[i].l, line_x[i].r - 1, line_x[i].sit, val_x);
        S_y.Update(1, line_y[i].l, line_y[i].r - 1, line_y[i].sit, val_y);
        sum += abs(S_x.tr[1].len - last_x) + abs(S_y.tr[1].len - last_y);
        last_x = S_x.tr[1].len;
        last_y = S_y.tr[1].len;
    }

    printf("%lld\n", sum);

    return 0;
}

标签:rt,周长,val,int,tr,MAXN,扫描线,模板,struct
来源: https://www.cnblogs.com/TSTYFST/p/16584809.html