ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

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

2022-08-14 09:30:26  阅读:174  来源: 互联网

标签:rt 周长 val int tr MAXN 扫描线 模板 struct


先开坑,晚上再写。

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

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有