文章目录
AT_abc203_e ABC203E White Pawn
题目描述
设 N N N 为正整数。有一个 ( 2 N + 1 ) × ( 2 N + 1 ) (2N+1)\times (2N+1) (2N+1)×(2N+1) 的棋盘,行和列的编号分别为 0 0 0 到 2 N 2N 2N,位于第 i i i 行第 j j j 列的格子记作 ( i , j ) (i,j) (i,j)。
棋盘上有一个白色兵,最初放在 ( 0 , N ) (0,N) (0,N)。有 M M M 个黑色兵,第 i i i 个黑色兵放在 ( X i , Y i ) (X_i, Y_i) (Xi,Yi)。
当白色兵在 ( i , j ) (i,j) (i,j) 时,你可以通过以下任一操作移动白色兵:
- 若 0 ≤ i ≤ 2 N − 1 0\leq i\leq 2N-1 0≤i≤2N−1, 0 ≤ j ≤ 2 N 0\leq j\leq 2N 0≤j≤2N,且 ( i + 1 , j ) (i+1,j) (i+1,j) 没有黑色兵,则可以将白色兵移动到 ( i + 1 , j ) (i+1,j) (i+1,j)。
- 若 0 ≤ i ≤ 2 N − 1 0\leq i\leq 2N-1 0≤i≤2N−1, 0 ≤ j ≤ 2 N − 1 0\leq j\leq 2N-1 0≤j≤2N−1,且 ( i + 1 , j + 1 ) (i+1,j+1) (i+1,j+1) 有黑色兵,则可以将白色兵移动到 ( i + 1 , j + 1 ) (i+1,j+1) (i+1,j+1)。
- 若 0 ≤ i ≤ 2 N − 1 0\leq i\leq 2N-1 0≤i≤2N−1, 1 ≤ j ≤ 2 N 1\leq j\leq 2N 1≤j≤2N,且 ( i + 1 , j − 1 ) (i+1,j-1) (i+1,j−1) 有黑色兵,则可以将白色兵移动到 ( i + 1 , j − 1 ) (i+1,j-1) (i+1,j−1)。
黑色兵不能移动。
请你求出,经过若干次操作后,白色兵最终可以到达 ( 2 N , Y ) (2N,Y) (2N,Y) 的不同 Y Y Y 的个数。
输入格式
输入通过标准输入给出,格式如下:
N N N M M M X 1 X_1 X1 Y 1 Y_1 Y1 : : : X M X_M XM Y M Y_M YM
输出格式
输出答案。
输入输出样例 #1
输入 #1
2 4
1 1
1 2
2 0
4 2
输出 #1
3
输入输出样例 #2
输入 #2
1 1
1 1
输出 #2
0
说明/提示
限制条件
- 1 ≤ N ≤ 10 9 1\leq N\leq 10^9 1≤N≤109
- 0 ≤ M ≤ 2 × 10 5 0\leq M\leq 2\times 10^5 0≤M≤2×105
- 1 ≤ X i ≤ 2 N 1\leq X_i\leq 2N 1≤Xi≤2N
- 0 ≤ Y i ≤ 2 N 0\leq Y_i\leq 2N 0≤Yi≤2N
- ( X i , Y i ) ≠ ( X j , Y j ) (X_i, Y_i)\neq (X_j, Y_j) (Xi,Yi)=(Xj,Yj)( i ≠ j i\neq j i=j)
- 所有输入均为整数。
样例解释 1
可以分别如下移动到 ( 4 , 0 ) (4,0) (4,0)、 ( 4 , 1 ) (4,1) (4,1)、 ( 4 , 2 ) (4,2) (4,2) 这三个位置:
- ( 0 , 2 ) → ( 1 , 1 ) → ( 2 , 1 ) → ( 3 , 1 ) → ( 4 , 2 ) (0,2)\to (1,1)\to (2,1)\to (3,1)\to (4,2) (0,2)→(1,1)→(2,1)→(3,1)→(4,2)
- ( 0 , 2 ) → ( 1 , 1 ) → ( 2 , 1 ) → ( 3 , 1 ) → ( 4 , 1 ) (0,2)\to (1,1)\to (2,1)\to (3,1)\to (4,1) (0,2)→(1,1)→(2,1)→(3,1)→(4,1)
- ( 0 , 2 ) → ( 1 , 1 ) → ( 2 , 0 ) → ( 3 , 0 ) → ( 4 , 0 ) (0,2)\to (1,1)\to (2,0)\to (3,0)\to (4,0) (0,2)→(1,1)→(2,0)→(3,0)→(4,0)
另一方面,无法移动到 ( 4 , 3 ) (4,3) (4,3) 和 ( 4 , 4 ) (4,4) (4,4)。因此,输出 3 3 3。
样例解释 2
无法将白色兵从 ( 0 , 1 ) (0,1) (0,1) 移动到其他位置。
由 ChatGPT 4.1 翻译
题解
简要题意:

简单模拟一下样例就会发现:
- 如果一行一个黑子都没有,那么对答案没有帮助,原来位置的白子直接下移一格即可
- 如果白子想脱离横坐标 N,只能是借助斜下方的黑子
所以我们只要枚举所有黑子的位置去讨论答案就好了(呼应了M<=2e5但N<=1e9的数据范围)

看起来有点像dp的转移,可以考虑从上到下枚举有黑子的行,存储当前所有白子可能出现的列集合S(最多2N个);
再枚举当前行的黑子,判断两个事:
- 其斜上方是否存在白子,若存在,把它的纵列加入S
- 其正上方是否存在白子,若存在,把它的纵列从S中移出(因为正下方有黑子时白子没办法继续下移了)
存储黑子可以用map,自动按照第一、二维排序。
考虑如何维护集合S,发现我们需要快速查找是否存在对应下标以及插入、删除操作,不难想到用set维护
时间复杂度降至O(mlogm)
cpp
// code by https://www.luogu.com.cn/article/ref58umu
#include <bits/stdc++.h>
#define ll long long
using namespace std;
int main()
{
int n,m;
scanf("%d%d",&n,&m);
map<int,vector<int>> Map;
set<int> Set;
for(int i=1;i<=m;i++)
{
int x,y;
scanf("%d%d",&x,&y);
Map[x].push_back(y);
}
Set.insert(n);
for(auto i:Map)
{
vector<int> in,out;
for(int j:i.second)
{
if(Set.count(j)) out.push_back(j);
if(Set.count(j-1)||Set.count(j+1)) in.push_back(j);
}
for(int j:out) Set.erase(j);
for(int j:in) Set.insert(j);
}
printf("%d",Set.size());
return 0;
}