首页 > 其他分享 >【学习笔记】扫描线

【学习笔记】扫描线

时间:2024-02-16 17:11:58浏览次数:30  
标签:ch sum namespace 笔记 学习 扫描线 isdigit include getchar

bilibili:BV1Mm411D7kr

讲了一下。

模板代码:

面积并:

#include <cstring>
#include <iostream>
#include <algorithm>
#define int long long
using namespace std;

namespace IO
{
    template<typename T>
    T read(T x)
    {
        T sum = 0, opt = 1;
        char ch = getchar();
        while(!isdigit(ch)) opt = (ch == '-') ? -1 : 1, ch = getchar();
        while( isdigit(ch)) sum = (sum << 1) + (sum << 3) + (ch ^ 48), ch = getchar();
        return sum * opt;
    }
}
#define read IO::read(0)

const int N = 1e5 + 5;

int n;
int x[N << 1];
int ans;

struct Segment_Tree
{
    struct Node{
        int l, r, len, sum;
    }tr[N << 4];

    void push_up(int u)
    {
        if(tr[u].sum){
            tr[u].len = x[tr[u].r + 1] - x[tr[u].l];
        }
        else tr[u].len = tr[u << 1].len + tr[u << 1 | 1].len;
    }
    void build(int u, int l, int r)
    {
        tr[u] = {l, r};
        if(l ==  r) return ;
        int mid = (l + r) >> 1;
        build(u << 1, l, mid);
        build(u << 1 | 1, mid + 1, r);
        push_up(u);
    }
    void update(int u, int l, int r, int c)
    {
        if(r <= x[tr[u].l] || x[tr[u].r + 1] <= l) return ;
        if(l <= x[tr[u].l] && x[tr[u].r + 1] <= r) {
            tr[u].sum += c;
            push_up(u);
            return ;
        }
        int mid = (tr[u].l + tr[u].r) >> 1;
        update(u << 1, l, r, c);
        update(u << 1 | 1, l, r, c);
        push_up(u);
    }
}seg;

struct node
{
    int l, r, h, mark;
}line[N << 1];

inline bool cmp(node a, node b)
{
    return a.h < b.h;
}

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

        x[i * 2 - 1] = x1, x[i * 2] = x2;
        line[i * 2 - 1] = {x1, x2, y1, 1};
        line[i * 2] = {x1, x2, y2, -1};
    }    
    n <<= 1;
    sort(x + 1, x + 1 + n);
    sort(line + 1, line + 1 + n, cmp);

    int len = unique(x + 1,x + 1 + n) - x - 1;

    seg.build(1, 1, len - 1);

    for(int i = 1;i < n;i ++ ){
        seg.update(1, line[i].l, line[i].r, line[i].mark);
        ans += seg.tr[1].len * (line[i + 1].h - line[i].h);
    }
    cout << ans << endl;

}

signed main()
{
    int T = 1;
    while(T -- ) work();
    return 0;
}

周长并:

#include <cstring>
#include <iostream>
#include <algorithm>
#include <cmath>

using namespace std;

namespace IO
{
    template<typename T>
    T read(T x)
    {
        T sum = 0, opt = 1;
        char ch = getchar();
        while(!isdigit(ch)) opt = (ch == '-') ? -1 : 1, ch = getchar();
        while( isdigit(ch)) sum = (sum << 1) + (sum << 3) + (ch ^ 48), ch = getchar();
        return sum * opt;
    }
}
#define read IO::read(0)
int ans;

const int N = 1e5 + 5;
int x[N << 1];
struct Segment_Tree
{
    struct Node
    {
        int l, r, sum, len, c;
        bool el, er;
    }tr[N << 4];

    void push_up(int u)
    {
        if(tr[u].sum){
            tr[u].len = x[tr[u].r + 1] - x[tr[u].l];
            tr[u].el = tr[u].er = true;
            tr[u].c = 1;
        }
        else{
            tr[u].len = tr[u << 1].len + tr[u << 1 | 1].len;
            tr[u].el = tr[u << 1].el;
            tr[u].er = tr[u << 1 | 1].er;
            tr[u].c = tr[u << 1].c + tr[u << 1 | 1].c;
            if(tr[u << 1].er && tr[u << 1 | 1].el) {
                tr[u].c -= 1;
            }
        }
    }

    void build(int u, int l, int r)
    {
        tr[u] = {l, r, 0, 0, 0, false, false};
        if(l == r) return ;
        int mid = (l + r) >> 1;
        build(u << 1, l, mid), build(u << 1 | 1, mid + 1, r);
        push_up(u);
    }

    void update(int u, int l, int r, int c)
    {
        if(r <= x[tr[u].l] || x[tr[u].r + 1] <= l) return ;
        if(l <= x[tr[u].l] && x[tr[u].r + 1] <= r) {
            tr[u].sum += c;
            push_up(u);
            return ;
        }
        int mid = (tr[u].l + tr[u].r) >> 1;
        update(u << 1, l, r, c);
        update(u << 1 | 1, l, r, c);
        push_up(u);
    }
}seg;

struct node{
    int l, r, h, mark;
}line[N << 1];

bool cmp(node a, node b)
{
    if(a.h == b.h) return a.mark > b.mark;
    return a.h < b.h;
}
void work()
{
    int n = read;
    for(int i = 1;i <= n;i ++ ){
        int x1 = read, y1 = read, x2 = read, y2 = read;
        x[i * 2 - 1] = x1, x[i * 2] = x2;
        line[i * 2 - 1] = {x1, x2, y1, 1};
        line[i * 2] = {x1, x2, y2, -1};
    }
    n <<= 1;
    sort(x + 1, x + 1 + n);
    sort(line + 1, line + 1 + n, cmp);

    int len = unique(x + 1,x + 1 + n) - x - 1;
    seg.build(1, 1, len - 1);
    int last = 0;
    for(int i = 1;i < n;i ++ ){
        seg.update(1, line[i].l, line[i].r, line[i].mark);
        ans += 2 * (line[i + 1].h - line[i].h) * seg.tr[1].c;
        ans += abs(last - seg.tr[1].len);
        last = seg.tr[1].len;
    }
    ans += line[n].r - line[n].l;
    cout << ans << endl;
}

int main()
{
    int T = 1;
    while(T -- ) work();
    return 0;
}

标签:ch,sum,namespace,笔记,学习,扫描线,isdigit,include,getchar
From: https://www.cnblogs.com/DreamerBoy/p/18017291

相关文章

  • 前端知识点学习汇总,温故而知新
    前端知识点学习汇总,温故而知新1.CSS行内样式表:权重高,div2.内部样式表,写在headerstyle里:结构+样式选择器{属性1:属性值1;属性2:属性值2}3.外部样式表:style.css,将结构和样式分开<head><linkrel="stylesheet"href="css/style.css"></head>样式表优点缺点控制范......
  • 通过注解实现本地缓存caffeine的学习
    注解源码如下1@Target(ElementType.METHOD)2@Retention(RetensionPolicy.RUNTIME)3@Documented4public@interfaceRvcCache{5Strngkey();6Stringid()defaultStringUtils.EMPTY;7}1@Component2@Aspect3@RequiredArgsConstructor4......
  • 李宏毅《机器学习》总结 - BERT(待填)
    BERT实际上是一个tranformerencoder,输入一串向量输出相同个数的向量。以下以句子为例,句子可以认为是一串向量。pre-train如何训练BERT呢(事实上应该是预训练,pre-train)?一个常用的方法是做填空题。即,随机挖去一些字,让模型学习如何去填空。其中这个“挖去”也有好几种方法(如......
  • (学习日记)一、Web框架-HTML标签-网页请求
    1.快速开发网站render_template是Flask框架的一个函数,用于渲染模板并生成动态的HTML文件app=Flask(name,template_floder(''路径''))构造一个Flask类赋给app,template_floder修改寻找模板的默认路径,默认是当前目录下的templates文件(没有则需要创建一个目录文件)fromflask......
  • (学习日记)三、BootSrap-JavaScript
    6.BootStrap6.1什么是bootstrap?-别人写好的css模板-Bootstrap中文网(bootcss.com)<!DOCTYPEhtml><html><head><title>BootStrap_Demo</title><metacharset="UTF-8"><linkrel="stylesheet"href=&quo......
  • (学习日记)六、Ajax请求
    15.Ajax请求浏览器向网站发送请求时:GETPOST特点:页面会刷新。也可以基于Ajax向后台发送请求(偷偷发送请求)依赖jQuery编写ajax$.ajax({url:"发送的地址",type:"post",data:{n1:123,n2:456,}success:function(res){co......
  • (学习日记)四、数据库MySQL
    1.初识网站默认编写的网站是静态的动态需要用到web框架的功能fromflaskimportFlask,render_templateapp=Flask(__name__)@app.route("/index")defindex():users={"Wu":"1","Liu":"2","Deng":"3"}#此处的数......
  • 机器学习中的10种非线性降维技术对比总结
    降维意味着我们在不丢失太多信息的情况下减少数据集中的特征数量,降维算法属于无监督学习的范畴,用未标记的数据训练算法。尽管降维方法种类繁多,但它们都可以归为两大类:线性和非线性。线性方法将数据从高维空间线性投影到低维空间(因此称为线性投影)。例子包括PCA和LDA。非线性......
  • 读十堂极简人工智能课笔记03_遗传算法与进化
    1. 寻找正确答案1.1. 卡尔·西姆斯1.1.1. 计算机图形艺术家和研究者1.1.2. 演示过数字进化之创造性和新颖性的先驱1.1.3. 1994年1.1.3.1. 创造一批能游泳、走路、跳跃,甚至互相竞争的虚拟动物震惊了整个科学界1.1.3.2. 它们的人工大脑却是个极其复杂的网络,信息经由传......
  • Arduino学习笔记
    教程ArduinoUno单片机零基础入门学用Arduino@B站.太极创客ArduinoNano单片机2023年ArduinoNano教程@B站.唐老思Arduino核心板ArduinoNanoArduino第三方库ArduinoLibraryList......