Snowy Smile【扫描线】【2019 杭电多校6】

2023-11-17

HDU-6638 题目链接



  比赛的时候只在拼命的想怎么去优化O(N^3)的那个之前所认为的标准解法,没想到,这就是一道O(N^2 * logN)的扫描线。

  我们可以固定上下两个区间,然后在固定的区域中,就是一维的空间了,我们直接在这一维里去查询即可,然后去寻找区间最大连续子段即可,很方便的。

  区间最大连续子段:

我们要查最大左端点,最大右端点,还有整个区间段的和,以及该区间段内的最大值。

然后维护左右段最大连续,都是去比较,子区间的端点最大连续 和 子区间整个和加上另一个子区间的该方向最大连续。

然后区间最大值,就是去比较左右最大值,左右连续,左子区间的右连续和右子区间的左连续之和,这几个的最大值。

#include <iostream>
#include <cstdio>
#include <cmath>
#include <string>
#include <cstring>
#include <algorithm>
#include <limits>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <map>
#define lowbit(x) ( x&(-x) )
#define pi 3.141592653589793
#define e 2.718281828459045
#define INF 0x3f3f3f3f
#define HalF (l + r)>>1
#define lsn rt<<1
#define rsn rt<<1|1
#define Lson lsn, l, mid
#define Rson rsn, mid+1, r
#define QL Lson, ql, qr
#define QR Rson, ql, qr
#define myself rt, l, r
#define MAX_3(x, y, z) max(x, max(y, z))
#define MAX_6(a, b, c, d, f, g) max(max(a, b), max(max(c, d), max(f, g)))
using namespace std;
typedef unsigned long long ull;
typedef long long ll;
const int maxN = 2007;
int N, lsan_x[maxN], lsan_y[maxN], len_x, len_y;
vector<int> vt[maxN];
struct node
{
    int x, y; ll val;
    node(int a=0, int b=0, ll c=0):x(a), y(b), val(c) {}
}a[maxN];
bool cmp(node e1, node e2) { return e1.x == e2.x ? e1.y < e2.y : e1.x < e2.x; }
struct make_Tree
{
    ll mx, lm, rm, all;
    make_Tree(ll a=0, ll b=0, ll c=0, ll d=0):mx(a), lm(b), rm(c), all(d) {}
}tree[maxN<<2];
void buildTree(int rt, int l, int r)
{
    tree[rt] = make_Tree();
    if(l == r) return;
    int mid = HalF;
    buildTree(Lson); buildTree(Rson);
}
inline void pushup(int rt)
{
    if(tree[lsn].lm > tree[lsn].all + tree[rsn].lm) tree[rt].lm = tree[lsn].lm;
    else tree[rt].lm = tree[lsn].all + tree[rsn].lm;
    
    if(tree[rsn].rm > tree[rsn].all + tree[lsn].rm) tree[rt].rm = tree[rsn].rm;
    else tree[rt].rm = tree[rsn].all + tree[lsn].rm;
    
    tree[rt].all = tree[lsn].all + tree[rsn].all;
    tree[rt].mx = MAX_6(tree[rt].lm, tree[rt].rm, tree[lsn].mx, tree[rsn].mx, tree[lsn].rm + tree[rsn].lm, tree[rt].all);
}
void update(int rt, int l, int r, int qx, ll val)
{
    if(l == r)
    {
        if(val >= 0) tree[rt] = make_Tree(val, val, val, val);
        else tree[rt] = make_Tree(0, 0, 0, val);
        return;
    }
    int mid = HalF;
    if(qx <= mid) update(Lson, qx, val);
    else update(Rson, qx, val);
    pushup(rt);
}
inline ll query(int rt, int l, int r, int ql, int qr)
{
    if(ql <= l && qr >= r) return tree[rt].mx;
    int mid = HalF;
    if(qr <= mid) return query(QL);
    else if(ql > mid) return query(QR);
    else
    {
        ll ans = tree[lsn].rm + tree[rsn].lm;
        ans = MAX_3(ans, query(QL), query(QR));
        return ans;
    }
}
int main()
{
    int Cas; scanf("%d", &Cas);
    while(Cas--)
    {
        scanf("%d", &N);
        for(int i=1; i<=N; i++) vt[i].clear();
        for(int i=1; i<=N; i++)
        {
            scanf("%d%d%lld", &a[i].x, &a[i].y, &a[i].val);
            lsan_x[i] = a[i].x; lsan_y[i] = a[i].y;
        }
        sort(lsan_x + 1, lsan_x + N + 1);
        sort(lsan_y + 1, lsan_y + N + 1);
        len_x = (int)(unique(lsan_x + 1, lsan_x + N + 1) - lsan_x - 1);
        len_y = (int)(unique(lsan_y + 1, lsan_y + N + 1) - lsan_y - 1);
        for(int i=1; i<=N; i++)
        {
            a[i].x = (int)(lower_bound(lsan_x + 1, lsan_x + len_x + 1, a[i].x) - lsan_x);
            a[i].y = (int)(lower_bound(lsan_y + 1, lsan_y + len_y + 1, a[i].y) - lsan_y);
        }
        sort(a + 1, a + N + 1, cmp);
        int tot = 0;
        for(int i=1, j=0; i<=N; )
        {
            j = i + 1;
            while(a[j].x == a[i].x && a[j].y == a[i].y)
            {
                a[i].val += a[j].val;
                j++;
            }
            a[++tot] = node(a[i].x, a[i].y, a[i].val);
            i = j;
        }
        for(int i=1; i<=tot; i++)
        {
            vt[a[i].x].push_back(i);
        }
        ll ans = 0;
        for(int i=1; i<=len_x; i++)
        {
            buildTree(1, 1, len_y);
            ll sum[maxN] = {0};
            for(int j=i; j<=len_x; j++)
            {
                int len = (int)vt[j].size();
                for(int k=0, pos; k<len; k++)
                {
                    pos = vt[j][k];
                    sum[a[pos].y] += a[pos].val;
                    update(1, 1, len_y, a[pos].y, sum[a[pos].y]);
                }
                ans = max(ans, query(1, 1, len_y, 1, len_y));
            }
        }
        printf("%lld\n", ans);
    }
    return 0;
}

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Snowy Smile【扫描线】【2019 杭电多校6】 的相关文章

随机推荐

  • django-admin.py startproject HelloWorld创建文件提示invalid syntax

    直接用win R 输入cmd 输入python 然后输入django admin py startproject HelloWorld创建文件提示invalid syntax 解决方法 直接在cmd下执行语句 即可生成Helloworld项
  • MybatisPlus入门和分页和条件查询里面的条件和null值的处理方式和查询投影和查询条件设置和id生成相关和逻辑删除

    MybatisPlus 简化了mybatis之前的在springboot整合MyBatis时需要自己写sql语句在接口中 现在只需要让接口继承BaseMapper lt 实体类 gt 然后在测试类中接口 增删改查方法 即可 不用像sprin
  • MMEditing代码阅读笔记一:main()函数中的build_model()

    MMEditing代码阅读笔记一 main 函数中的build model 小白一枚 编程功底很弱 接触MMEditing这套代码 刚开始小眉头一皱 鼠标见点来点去不知道咋个回事 网上又没有关于MMEditing代码阅读的相关阐述 眉头更皱
  • LEFT JOIN右表为空也查出数据

    SELECT A B type FROM Table A A LEFT JOIN Table B B ON A id B id WHERE B type 1 改为 SELECT A B type FROM Table A A LEFT JO
  • 在WinForm中屏蔽中文输入法

    在WinForm的开发中 有时有些特殊的要求 例如 在某个Form上彻底屏蔽中文输入法 使之不能切换到中文输入 不能进行中文输入 这个问题看上去简单 实现起来并没有想象中的简单 下面 把我做的几个实验依次列举 就会发现 其实实现起来还是有一
  • websocket菜鸟教程(1.1)

    创建自己的websocket服务 先了解node js websocket 的基本使用https www npmjs com package nodejs websocket 第一步先安装 npm install nodejs websoc
  • mysql5.6安装步骤详细_详解MySQL5.6安装步骤

    是开放源码的小型关系型数据库管理系统 目前MySQL被广泛应用于在Internet上的中小型网站中 但是对于刚接触MySQL数据库服务器的朋友来说 是非常陌生的 那么现在爱站小编为大家详解MySQL5 6步骤 1 点击下载好的安装文件 出现
  • console控制台错误及处理过程

    1 ERROR Failed to execute goal org apache maven plugins maven compiler plugin 2 5 1 compile default compile on project l
  • 为什么组件中的data是一个函数而不是一个对象?

    JS中的对象是引用类型的数据 当多个实例引用同一个对象时 只要有一个实例对这个对象进行操作 其他实例中的数据也会发生变化 而在vue中 更想要每个组件都有自己的数据 不会互相干扰 所以组件的数据不能写成对象的形式而要是函数的形式 数据以函数
  • Ubuntu下非常给力的下载工具

    Windows下的下载工具 迅雷 之所以下载速度快 乃是它能搜索资源 为己所用 而不是仅仅从原始地址这单一资源处下载 Ubuntu下也有类似的工具 那就是aira2 aira2是一个命令行下载工具 可以配合其他图形界面的下载软件使用 我用的
  • HyperLogLog数据结构

    基数计数 cardinality counting 通常用来统计一个集合中不重复的元素个数 例如统计某个网站的UV 或者用户搜索网站的关键词数量 数据分析 网络监控及数据库优化等领域都会涉及到基数计数的需求 要实现基数计数 最简单的做法是记
  • python读取csmar_如何优雅的把CSMAR(国泰安)数据导入R

    前言CSMAR 国泰安 数据库是经济金融相关的科研工作者用到的最多的数据库之一 它提供了丰富全面的上市公司财务及金融数据 以及一些行业宏观层面的数据 但是 它并没有像WRDS 沃顿研究数据服务 等数据库提供丰富接口 如SAS R等 供下载
  • 论文阅读笔记之——《Multi-level Wavelet-CNN for Image Restoration》及基于pytorch的复现

    本博文是MWCNN的阅读笔记 论文的链接 https arxiv org pdf 1805 07071 pdf 代码 https github com lpj0 MWCNN 仅仅是matlab代码 通过参考代码 对该网络在pytorch框架
  • C语言库函数——快排函数qsort()

    目录 一 函数原型 二 函数介绍 三 函数使用 常见写法 比较函数 四 函数实例 1 int型数组 2 double型数组 3 char型数组 4 字符串 5 结构体 一级结构 二级结构 一 函数原型 void qsort void bas
  • CAN协议详解-01

    CAN 是控制器局域网络 Controller Area Network 的简称 它是由研发和生产汽车电子产品著称的德国 BOSCH 公司开发的 并最终成为国际标准 ISO11519以及ISO11898 是国际上应用最广泛的现场总线之一 差
  • 《机器学习实战》第14章学习笔记(数据约简工具---SVD)

    一 SVD基本原理 提取这些信息的方法称为奇异值分解 Singular Value Decomposition SVD 在很多情况下 数据中的一小段携带了数据集中的大部分信息 其他信息则要么是噪声 要么就是毫不相关的信息 在线性代数中还有很
  • unity如何解决每次写完敲代码,调试时需要卡个进度条

    解决办法如下 勾选上之后程序就可以立刻运行起来了 再也不用一直卡进度条了 不过也有弊端的 会影响静态字段初始化有问题还有Dotween的一些效果会发生变化 谨慎避免入坑
  • armbian安装图形桌面_Linux的图形用户界面-你会选择哪个?

    时至今日 Linux在服务器端的地位是毋庸置疑的 其常见的命令行界面是相当稳定的 图形界面嘛 存在众多版本 兼容性有待进一步提升 常见的图形界面有 以ubuntu系统为例 Unity 这是Ubuntu自带的图形界面 相当炫 但吃内存比较大
  • 毕业设计-基于机器学习的中文文本分类算法

    目录 前言 课题背景和意义 实现技术思路 一 文本分类综述 二 文本分类相关技术简 1 文本处理过程 2 分类算法 3 分类算法评价方法 实现效果图样例 最后 前言 大四是整个大学期间最忙碌的时光 一边要忙着备考或实习为毕业后面临的就业升学
  • Snowy Smile【扫描线】【2019 杭电多校6】

    HDU 6638 题目链接 比赛的时候只在拼命的想怎么去优化O N 3 的那个之前所认为的标准解法 没想到 这就是一道O N 2 logN 的扫描线 我们可以固定上下两个区间 然后在固定的区域中 就是一维的空间了 我们直接在这一维里去查询即