ABC186 F - Rook on Grid 题解

news/2024/9/26 0:10:26

原题链接

Description

给定 \(H\)\(W\) 列的格网,其中有 \(M\) 个障碍,有一起点 \((1,1)\) ,可以横着或竖着走多个格子,求走两步以内可以达到的格子数。

Solution

显然我们先要维护:

\(x[i]\) 表示第 \(i\) 行第一个障碍的下标,若没障碍,则设为 \(W+1\)

\(y[i]\) 表示第 \(i\) 列第一个障碍的下标,若没障碍,则设为 \(H+1\)

那么容易统计答案:

对于第 \(i\) 行,两步之内可以到达的格子数为 \(x[i]-1\)

对于第 \(i\) 列,两步之内可以到达的格子数为 \(y[i]-1\)

接下来要考虑消去重复计算的格子。

对于上面两次统计,其实就是先往下走再往右走,和先往右走再往下走,假如我们已经统计完先下再右的个数,那么对于第 \(i\)\([1,y[i]-1]\) 的所有格子,若当前格子的左边有障碍的话,那么该格子只能由先右再下到达,反之,则该格子以及在第一次统计中对答案有贡献了。

因此,对于第二次统计,我们只需要当前列 \([1,y[i]-1]\) 的所有格子中左边有障碍的格子记录贡献,每统计完一列,就需要将该列中 \(x[j]==i\) 的格子打上标记。这个过程显然可以用树状数组进行维护。

Code

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<queue>
#include<map>
#include<vector>
using namespace std;
#define MAXN 200010
#define INF 0x3f3f3f3f
//#define int long long
int Read()
{int x=0,f=1;char c=getchar();while(c>'9'||c<'0'){if(c=='-')f=-f;c=getchar();}while(c>='0'&&c<='9'){x=x*10+c-48;c=getchar();}return x*f;
}
int n,h,w,t[MAXN];
int Lowbit(int x){return x&-x;}
void Add(int x,int val){for(;x<=h;x+=Lowbit(x))t[x]+=val;}
int Query(int x){int ans=0;for(;x;x-=Lowbit(x))ans+=t[x];return ans;}
int x[MAXN],y[MAXN];
vector<int> qwq[MAXN];
int main()
{h=Read();w=Read();n=Read();for(int i=1;i<=h;i++) x[i]=w+1;for(int i=1;i<=w;i++) y[i]=h+1;for(int i=1;i<=n;i++){int ax=Read(),ay=Read();x[ax]=min(x[ax],ay);y[ay]=min(y[ay],ax);}long long ans=0;for(int i=1;i<=y[1]-1;i++) ans+=x[i]-1;for(int i=y[1];i<=h;i++) x[i]=1;for(int i=1;i<=h;i++) qwq[x[i]].push_back(i);for(int i=1;i<=w;i++){if(y[i]==1) break;
//      cout<<i<<" "<<Query(y[i]-1)<<endl;ans+=Query(y[i]-1);for(int j=0;j<(int)qwq[i].size();j++)Add(qwq[i][j],1);}printf("%lld",ans);return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.ryyt.cn/news/64810.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈,一经查实,立即删除!

相关文章

Java中到底有哪些锁

乐观锁和悲观锁 不是具体的锁,是指看待并发同步的角度 悲观锁:对于同一个数据的并发操作,悲观锁认为自己在使用数据的时候一定有别的线程来修改数据,因此在获取数据的时候会先加锁,确保数据不会被别的线程修改。Java中,synchronized关键字和Lock的实现类都是悲观锁。 乐观…

Pyqt5 修改表格排序箭头

实现效果:代码from chatgptimport sys from PyQt5.QtWidgets import QApplication, QTableWidget, QTableWidgetItem, QVBoxLayout, QWidget from PyQt5.QtCore import Qtclass TableDemo(QWidget):def __init__(self):super().__init__()# 创建表格self.table_widget = QTabl…

day7[XTuner 微调个人小助手认知任务]

微调前用 internlm2-chat-1_8b 模型,通过 QLoRA 的方式来微调一个自己的小助手认知作为案例来进行演示

【算法】笔试题记录

哇今天做了道特别有意思的题。 编程就给了两道,第一题特别简单,a、b两个数,每次选其中一个数*2,这样操作两次,问最后得到的两数之和的期望值是多少。 简单吧?因为每次选择都有两种可能性,操作两次后就会有四种可能的结果(22)。其中有两个结果是重复的(2a, 2b),剩下两个…

使用AI进行需求分析的案例研究

生成式 AI 的潜在应用场景似乎无穷无尽。虽然这令人兴奋,但也可能让人不知所措。因此,团队在使用这项技术时需要有明确的目标:关键是要明确生成式 AI 在团队工作中能产生哪些实质性影响。 在软件工程中,一个引人注目的应用场景是需求分析。这是一个常常被忽视但充满挑战的环…

02 第三组(4个)进制转换

进制转换:二进制,十六进制、八进制、十进制 bin 二进制 oct 8进制 hex 十六进制 int 10进制二进制 和十进制#10进制转二进制 v1 = bin(48) print(v1)#二进制转10进制 v1 = 0b1010101 v2 = int(v1, base=2)八进制 和十进制#10进制转八进制 v1 = oct(48) print(v1)#八进制转1…

实验1_C语言输入输出和简单程序应用编程

任务一 1-1#include<stdio.h> int main() { printf(" O "); printf("<H>"); printf("I I"); printf(" O "); printf("<H>"); printf("I I"); return 0; }1-2#include<stdio.h> int main(…

初识vue

1.概述我眼中的vue,vue是前端开发的一个框架,可以大大提高开发的效率,最新的是vue3,企业目前使用vue2,其主要核心是V-VM-M的思想,作用是让数据和图像进行双向绑定,就是视图改变数据改变,数据改变视图改变. 2.在使用Vue时要应用文件vue.js在头部,在其他位置引用起不到作用3.在定…