Arson In Berland Forest【Codeforces 1262 E】【二维差分 + 二分答案】

2023-11-02

Codeforces Round #602 (Div. 2, based on Technocup 2020 Elimination Round 3) E


这道E题当真是HACK了不少人,先讲一下题意吧。

  有一个N*M的矩形,里面放了‘ X ’和‘ . ’两种类型的东西,我们想要用最大的' X '阵来覆盖完整个矩阵的' X ',问最大阵的变长是多少,并且这个最大阵可以看成是从一个点向外延伸多少次,且必须被看成是一个点向外延伸多少次,问的是最多的延伸次数,也就是(变成 - 1)/2。

  然后,一开始的时候呢,偷懒了,想了个(很容易被HACK,但还是敢交)先去求图中最小的最大阵的宽度或长度来先确定边长,然后就是直接构造,这样的方法(可以假装AC)

代码也在后面会给出来。

  现在啊,该说一下正解了,正解就是一个二分答案再加上二维差分,我们知道一维直线上的差分就是,我们要给一段区间[l, r]都加上1,我们可以在l这个位置上+1,在r+1这个位置上-1,然后做一个前缀和就可以了,那么对于二维平面,我们该有怎样的做法了呢?

  一样是用到了二维前缀和的思想。sum(x, y) = sum(x, y) + sum(x - 1, y) + sum(x, y - 1) - sum(x - 1 , y - 1)(这就是二维前缀和的思想了。)

  然后,我们可以去二分答案这个向外的延伸次数,我们就可以去对它进行check了。把所有覆盖了一整块S = (2 * lim) * (2 * lim)面积的,都做这样的操作,假设(x,y),现在是(x - lim, y - lim)和(x + lim, y + lim)这样的矩形,我们对(x - lim, y - lim)这个点上+1,对(x - lim, y + lim + 1)这个点-1,对(x + lim + 1, y - lim)这个点-1,对(x + lim + 1, y + lim + 1)这个点进行+1,这样就能保证经过二维前缀和之后的答案就是覆盖次数了,那么,假如这个点是一个'X'点,但是呢却没有被覆盖,很显然,这里的二分答案就偏大了。

正解Ac——Code

#include <iostream>
#include <cstdio>
#include <cmath>
#include <string>
#include <cstring>
#include <algorithm>
#include <limits>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <unordered_map>
#include <unordered_set>
#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 MP(a, b) make_pair(a, b)
using namespace std;
typedef unsigned long long ull;
typedef unsigned int uit;
typedef long long ll;
const int maxN = 1e6 + 7;
int N, M;
vector<int> mp[maxN], t[maxN];
vector<bool> X[maxN];
char s[maxN];
int Area(int lx, int ly, int rx, int ry) { return mp[rx][ry] - mp[lx - 1][ry] - mp[rx][ly - 1] + mp[lx - 1][ly - 1]; }
inline bool In_map(int x, int y) { return x >= 1 && y >= 1 && x <= N && y <= M; }
inline bool check(int lim)
{
    for(int i=0; i<=N + 1; i++) t[i].clear();
    for(int i=0; i<=M + 1; i++) t[0].push_back(0);
    for(int i=1; i<=N + 1; i++) for(int j=0; j<=M + 1; j++) t[i].push_back(0);
    int SS = (2 * lim + 1) * (2 * lim + 1);
    for(int i = lim + 1, x1, y1, x2, y2; i + lim<=N; i++)
    {
        for(int j = lim + 1; j + lim<=M; j++)
        {
            x1 = i - lim; y1 = j - lim; x2 = i + lim; y2 = j + lim;
            if(In_map(x1, y1) && In_map(x2, y2) && Area(x1, y1, x2, y2) == SS)
            {
                t[x1][y1]++; t[x1][y2 + 1]--; t[x2 + 1][y1]--; t[x2 + 1][y2 + 1]++;
            }
        }
    }
    for(int x=1; x<=N; x++)
    {
        for(int y=1; y<=M; y++)
        {
            t[x][y] = t[x][y] + t[x - 1][y] + t[x][y - 1] - t[x - 1][y - 1];
            if(X[x][y] && !t[x][y]) return false;
        }
    }
    return true;
}
int main()
{
    scanf("%d%d", &N, &M);
    for(int i=0; i<=M; i++) { mp[0].push_back(0); mp[N + 1].push_back(0); }
    for(int i=1, val; i<=N; i++)
    {
        mp[i].push_back(0);
        X[i].push_back(false);
        scanf("%s", s + 1);
        for(int j=1; j<=M; j++)
        {
            val = mp[i - 1][j] + mp[i][j - 1] - mp[i - 1][j - 1];
            if(s[j] == 'X')
            {
                val++;
                X[i].push_back(true);
            }
            else X[i].push_back(false);
            mp[i].push_back(val);
        }
    }
    int l = 0, r = min(N, M), mid, ans = 0;
    while(l <= r)
    {
        mid = (l + r) >> 1;
        if(check(mid))
        {
            l = mid + 1;
            ans = mid;
        }
        else r = mid - 1;
    }
    printf("%d\n", ans);
    int SS = (2 * ans + 1) * (2 * ans + 1);
    for(int i=1; i<=N; i++)
    {
        for(int j=1; j<=M; j++)
        {
            if(X[i][j] && In_map(i - ans, j - ans) && In_map(i + ans, j + ans) && Area(i - ans, j - ans, i + ans, j + ans) == SS) printf("X");
            else printf(".");
        }
        puts("");
    }
    return 0;
}
/*
2 2
XX
XX
*/

 

错误的但是也可以作为参考的解:

#include <iostream>
#include <cstdio>
#include <cmath>
#include <string>
#include <cstring>
#include <algorithm>
#include <limits>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <unordered_map>
#include <unordered_set>
#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 MP(a, b) make_pair(a, b)
using namespace std;
typedef unsigned long long ull;
typedef unsigned int uit;
typedef long long ll;
const int maxN = 1e6 + 7;
int N, M;
vector<int> mp[maxN];
vector<bool> X[maxN];
char s[maxN];
int Area(int lx, int ly, int rx, int ry) { return mp[rx][ry] - mp[lx - 1][ry] - mp[rx][ly - 1] + mp[lx - 1][ly - 1]; }
inline bool check(int x, int y) { return x >= 0 && y >= 0 && x <= N && y <= M; }
int main()
{
    scanf("%d%d", &N, &M);
    for(int i=0; i<=M; i++) { mp[0].push_back(0); mp[N + 1].push_back(0); }
    for(int i=1, val; i<=N; i++)
    {
        mp[i].push_back(0);
        X[i].push_back(false);
        scanf("%s", s + 1);
        for(int j=1; j<=M; j++)
        {
            val = mp[i - 1][j] + mp[i][j - 1] - mp[i - 1][j - 1];
            if(s[j] == 'X')
            {
                val++;
                X[i].push_back(true);
            }
            else X[i].push_back(false);
            mp[i].push_back(val);
        }
    }
    int ans = min(N, M), now = 0;
    for(int i=1; i<=N; i++)
    {
        now = 0;
        for(int j=1; j<=M; j++)
        {
            if(X[i][j]) now++;
            else if(now) { ans = min(ans, now); now = 0; }
        }
        if(now) ans = min(ans, now);
    }
    for(int j=1; j<=M; j++)
    {
        now = 0;
        for(int i=1; i<=N; i++)
        {
            if(X[i][j]) now++;
            else if(now) { ans = min(ans, now); now = 0; }
        }
        if(now) ans = min(ans, now);
    }
    ans = (ans - 1) / 2;
    int SS = (2 * ans + 1) * (2 * ans + 1);
    printf("%d\n", ans);
    for(int i=1; i<=N; i++)
    {
        for(int j=1; j<=M; j++)
        {
            if(!X[i][j]) { printf("."); continue; }
            if(check(i - ans - 1, j - ans - 1) && check(i + ans, j + ans) && Area(i - ans, j - ans, i + ans, j + ans) == SS) printf("X");
            else printf(".");
        }
        puts("");
    }
    return 0;
}
/*
2 2
XX
XX
*/

 

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

Arson In Berland Forest【Codeforces 1262 E】【二维差分 + 二分答案】 的相关文章

  • codeforces1169C 二分答案+思维

    1169C 1700的题 xff0c 然而比赛的时候没有做出来 题意 xff1a 给你一个n表示序列长度为n xff0c 还有一个m表示这个序列的最大值小于m 然后对这个数组进行多次操作 xff0c 一次操作为 对ai xff0c aj x
  • 每日一题:二分答案

    二分答案 题目 Daimayuan Online Judge 首先读入 n 和 k 然后读入序列 a 接下来使用 l 和 r 表示最小值的猜测区间 由于题目中规定了最小值和元素范围 因此我们可以将上界设置为 1e18 下界设置为 1 二分查
  • Codeforces Round #291 (Div. 2)

    题目链接contest 514 A Chewba ca and Number 不允许有前导零 所以如果第一位是9的话 需要特别考虑 一开始理解错了题意 又WA了呜呜呜 include
  • Balanced Ternary String【Codeforces Round #531 (Div. 3)D】【贪心、构造】

    题目链接 一道简单的构造 我们可以分成几个状态 因为所有的状态只有8个 所以 直接写每个状态即可 哎 被hack了 烦啊 谁让我写的好烂 好菜啊 呜呜呜 include
  • Acwing-4455. 出行计划

    暴力解法TLE了 过了70 的数据 include
  • Arson In Berland Forest【Codeforces 1262 E】【二维差分 + 二分答案】

    Codeforces Round 602 Div 2 based on Technocup 2020 Elimination Round 3 E 这道E题当真是HACK了不少人 先讲一下题意吧 有一个N M的矩形 里面放了 X 和 两种类型
  • 【复赛模拟试题】收费站(二分答案+Dijkstra)

    问题描述 在某个遥远的国家里 有n个城市 编号为1 2 3 n 这个国家的政府修建了m条双向的公路 每条公路连接着两个城市 沿着某条公路 开车从一个城市到另一个城市 需要花费一定的汽油 开车每经过一个城市 都会被收取一定的费用 包括起点和终
  • Business Cycle 【UVALive - 7501】【二分答案+思维处理】

    题目链接 14年的EC 银牌题 但是现在的大牛们进步神速 估计如今已经是道铜牌题了 具体我们先讲一下题意 一个长度为N的自环圈 每个点 1 N 上有自己对应的权值 可能为负数 我们用一个初始值进入这个环 每次走到一个节点的时候会加上这个节点
  • 动物森友会【科大讯飞杯L题】【二分答案+最大流】

    题目链接 有N个物品 一周有7天 然后呢 要对应的每个物品都要达到各自的需求数量 于是问 最少需要几天才可以达到要求 很明显的 这是线性关系的 我们可以用二分答案来解决这个问题 然后呢怎么知道是否满足条件也就是来确定的 要满足每个物品都要拿
  • Salary Changing【Codeforces 1251 D】【二分答案】

    Educational Codeforces Round 75 Rated for Div 2 D 题意 有N名员工和S元钱 然后我们想知道在每一名员工有薪资要求在 li ri 的情况下 我们如何在总共就S元钱的情况下做到员工薪资的中位数最
  • The Lost House【树形DP+期望+构造路径】

    题目链接 POJ 2057 题意 有一棵N的点的树 开始的时候蜗牛在1号结点 它不知道它的家在哪个叶子结点 树上的有些结点有虫虫 虫虫会告诉你 你的家是否在以它所在结点为根的子树上 现在需要你规划走的方案 使得找到哪个叶子结点才是家的所走路
  • Educational Codeforces Round 67 (Rated for Div. 2)

    contest链接 A Stickers and Toys time limit per test 2 seconds memory limit per test 256 megabytes input standard input out
  • [CTSC2008]网络管理Network【树状数组+主席树】

    题目链接 题意 有一棵N个点的树 每个点有对应的权值 现在有这样的操作 0 a b 将a点的权值改成为b k a b 询问a到b的链上第k大的权值是几 我们可以用dfs序的树上差分的方式来解决这个问题 可以发现 求u到v的信息 其实就是求u
  • Array K-Coloring【Codeforces Round #531 (Div. 3)B】【构造】

    题目链接 题意 给你N长度的数组 以及K种颜色 要求的是我们能否使用全部K种颜色来填充每个数组元素 其中数组中的每个相同值元素的染色是不能相同的 并且 要用完所有K个颜色 能达到以上要求 则是YES并输出染色 否则 只有NO 我WA在了第6
  • 差分数组是个啥?能干啥?怎么用?(差分详解+例题)

    差分数组是个啥 差分数组很明显就是个数组呗 本菜鸡学的比较浅 先说一下我自己认识的差分数组吧 先解释一下什么是 差分 差分其实就是数据之间的差 什么数据的差呢 就是上面所给的原始数组的相邻元素之间的差值 我们令 d i a i 1 a i
  • 【CQOI 2015】任务查询系统

    题目 传送门 题目描述 最近实验室正在为其管理的超级计算机编制一套任务管理系统 而你被安排完成其中的查询部分 超级计算机中的任务用三元组 Si Ei Pi 描述 Si Ei Pi 表示任务从第 Si 秒开始 在第 Ei 秒后结束 第 Si
  • [SDOI2012]拯救小云公主【bfs+二分答案】

    题目链接 正难则反 要直接求从起点到终点的最大距离 不妨反过来求最小的可以阻止骑士从起点到终点的对于全体圆的最小半径 那么 就是阻止从左上角到右下角的所有相交圆 于是 就是要变成没有从左上角到右下角的相交圆才可以 那么不妨跑一个bfs来判断
  • 二分答案总结&例题解析

    对于二分我们最初的了解 就是在一个一次函数中 对于要求的点 x y 已知y 对于包含x值的区间二分 根据函数值与y比较 逐步靠近要求的点 直到最终求出要求的点 在程序执行时 二分的时间复杂度为logn 可以极大的减少查找的时间 二分的应用
  • Match Points【Codeforces 1156C】【二分答案】

    题目链接 题意有点像上海EC某年的一道铜牌题 具体是哪年记不得了 我们要去N个的关系 使得最多的匹配对达到他们的差值 Z 这样的情况 有这样的一组数据可以很好的反映这道题为什么有人会WA了 4 3 1 4 5 7 但是 同时也证明了 我们取
  • 深入C++的拷贝构造和赋值函数 (深拷贝,浅拷贝)

    参考了 点击打开链接以及 高质量程序设计指南C C语言 说明 拷贝构造函数是一种特殊的构造函数 相同类型的类对象是通过拷贝构造函数来完成整个复制过程的 函数的名称必须和类名称一致 它的参数是唯一的 该参数是const类型的引用变量 例如 类

随机推荐

  • HashPasswordForStoringInConfigFile 已过时

    https blog csdn net ibenxiaohai123 article details 77453340 https docs microsoft com en us dotnet api system security cr
  • 【ES6】对象的扩展

    文章目录 一 对象的扩展 二 用法详解 1 属性的简洁表示 2 属性名表达式 3 Object is 4 扩展运算符与Object assign 5 in 6 对象的遍历方式 一 对象的扩展 属性的简洁表示法 属性名表达式 Object i
  • Qt-初识

    文章目录 前言 一 pandas是什么 二 使用步骤 1 引入库 2 读入数据 总结 一 是什么 Qt是一个由Qt Company开发的跨平台C 图形用户界面应用程序开发框架 它既可以开发GUI程序 也可用于开发非GUI程序 比如控制台工具
  • MATLAB 2018中LSTM时间序列分类

    从MATLAB2018a开始 增加了LSTM神经网络工具箱 上图将时序数据分类为categorical 0 或categorical 1 每一行代码解释如下 该时序数据每一个时刻都是一个11维的列向量 隐藏层节点为270 分为两类0或1 构
  • Ciclop horus源码编译

    1 简介 Ciclop是西班牙BQ公司开源的一个DIY 3D扫描仪Horus则是配套开发的3D扫描软件 这款Ciclop是完全开源的 该公司甚至把有关这台3D扫描仪的所有相关机械设计 电子 软件 算法 数学和进行的测试都公布在了开源社区上
  • mysql 参数单位_MySQL参数配置

    参数名称 参数说明 缺省值 最低版本要求 user 数据库用户名 用于连接数据库 所有版本 passWord 用户密码 用于连接数据库 所有版本 useUnicode 是否使用Unicode字符集 如果参数characterEncoding
  • 数据结构学习系列之顺序表的两种删除方式

    方式1 在顺序表的末端删除所存储的数据元素 代码如下 示例代码 int delete seq list 1 list t seq list if NULL seq list printf 入参为NULL n return 1 if 0 se
  • WEB端测试点----整理

    目录 1 功能测试 1 1链接测试 1 2表单测试 1 3数据校验 1 4 cookies测试 1 5数据库测试
  • 【实战】k8s集群中通过docker容器部署Squid正向代理

    1 Squid简介 2 问题描述 3 k8s集群中容器化部署Squid 3 1 环境说明 3 2 在公网节点使用docker安装squid 3 3 配置受信 3 4 修改Squid配置文件 4 代理上网 4 1 为其它节点上的docker配
  • 基于改进 YOLOv5 的小目标检测论文代码复现

    使用yolov5 6 0源码 yolov5x yaml yolov5x pt 1 在主干网络中 加入CBAM 注意力模块增强网络特征提取能力 参考 加入CBAM YOLOv5 v6 0 backbone backbone from numb
  • 病毒相关网址

    病毒命名概述 https www symantec com security center a z https global ahnlab com site securitycenter viruscenter virusList do E
  • 华为snmpv3配置

    华为snmpv3配置 snmp agent 开启SNMP协议 snmp agent community read huawei acl 2001 只读属性为huawei 匹配acl 2001 snmp agent community wri
  • 一:单链表——⑤带环单链表的详细讲解

    今天看了一篇关于带环单链表精讲的文章 在这里给大家做一个总结 之前看过很多有关单链表带环的文章 但是有些文章讲的太文章化 不容易理解 理论性太强 接下来我会用最简单通俗易懂的语言解析这个问题 当你拿到一个单链表的数据信息时 我相信大部分的人
  • crontab执行脚本出错

    最近经常碰到关于crontab不能执行的 初步总结了有以下几个原因 第一 脚本的原因 大多数情况下 是我们的脚本的问题 这种问题导致crontab不能执行的概率占到70 以上 因为程序执行到某一步导致crontab终止执行 如 数据库访问出
  • 冒泡排序的理解

    冒泡排序将数组内的元素进行一定序列的算法 如 1 5 4 6 就变成 1 4 5 6 还可以 6 5 4 1 如何实现 例如 7 23 12 4 13 21 2 17 13 9 1 7与23比较 比较出最值 如果比较最大值 7 lt 23
  • 记录运行tensorflow报错及解决方法

    1 Could not load dynamic library libcudart so 11 0 dlerror libcudart so 11 0 cannot open shared 解决方法 安装cuda 1 下载cuda安装包
  • C#WinForm窗体内Panel容器中嵌入子窗体、程序主窗体设计例子

    C WinForm父级窗体内Panel容器中嵌入子窗体 程序主窗体设计例子 在项目开发中经常遇到父级窗体嵌入子窗体所以写了一个例子程序 顺便大概划分了下界面模块和配色 不足之处还望指点 主窗体窗体采用前面一篇博客设计扁平化窗体 C 自定义W
  • 用Python抢茅台脚本,转手纯赚一千!这不比什么兼职都管用?

    12 月我在朋友圈看到非常多的人开始在某东上抢茅台 抢到的话一瓶只要 1499 元 转手一卖就能净赚 1000 块钱 这简直就是白送钱的事嘛 就算不卖 自己囤着过个几年价格肯定又要上涨 像这种好事 我当然第一时间去体验了 抢了几天后 却抢了
  • 牛客网-OJ在线编程常见输入输出练习场(C++)

    牛客网 OJ在线编程常见输入输出练习场 C 主要分成数字和字符串输入输出两个部分 只选取几个有代表性的 详细可以去 牛客网 https ac nowcoder com acm contest 5647 from hr test questi
  • Arson In Berland Forest【Codeforces 1262 E】【二维差分 + 二分答案】

    Codeforces Round 602 Div 2 based on Technocup 2020 Elimination Round 3 E 这道E题当真是HACK了不少人 先讲一下题意吧 有一个N M的矩形 里面放了 X 和 两种类型