📜  门|门CS 2008 |问题 12(1)

📅  最后修改于: 2023-12-03 15:28:48.753000             🧑  作者: Mango

门|门CS 2008 |问题 12

这是门|门CS 2008考试中的一个编程问题,需要编写一个程序来实现。

问题描述

有 $n$ 扇门排成一排,每扇门都可以是开或者关的状态。 程序需要实现以下两种操作:

  1. 给定一个区间 $[L, R]$,将这个区间内所有的门状态取反。
  2. 查询第 $i$ 扇门的状态。
输入格式

第一行包含两个整数 $n$ 和 $m$,表示门的数量和操作的数量。

第二行包含 $n$ 个数字 $a_1, a_2, ..., a_n$,表示每扇门的初始状态。

接下来 $m$ 行,每行描述一个操作,格式如下:

  • 1 l r,表示将区间 $[l,r]$ 内的门状态取反。
  • 2 i,表示查询第 $i$ 扇门的状态。
输出格式

对于每个查询操作,输出一个整数,表示对应门的状态。

编程要求

你需要实现以下函数:

def door(n: int, m: int, a: List[int], opr: List[List[int]]) -> List[int]:
    pass
输入参数
  • n: 表示门的数量。$1 \leq n \leq 10^5$。
  • m: 表示操作次数。$1 \leq m \leq 10^5$。
  • a: 长度为 $n$ 的整数数组,表示门的初始状态。$a_i=0$ 表示第 $i$ 扇门初始状态为关,$a_i=1$ 表示第 $i$ 扇门初始状态为开。
  • opr: 长度为 $m$ 的二维整数数组,表示操作。$opr_i$ 表示第 $i$ 次操作。
输出参数
  • 返回一个长度为 $m$ 的整数数组,表示每次查询操作的结果,顺序与查询操作出现顺序相同。
注意事项
  • 保证所有区间都合法。即 $1\leq l\leq r\leq n$。
  • 输入保证合法。
样例

输入:

5 6
0 1 0 1 1
2 1
1 1 2
2 2
1 2 4
2 4
1 3 5

输出:

0 1 1
解题思路

对于这道题目,我们可以使用树状数组来解决。对于每个门的状态,用 $0$ 表示关,$1$ 表示开,那么我们只需要统计区间内开着的门的数量即可。

对于每次操作,如果是查询操作,那么我们可以直接通过二分查找获取结果。否则,我们需要将区间内的状态取反,也就是将 $1$ 变成 $0$,将 $0$ 变成 $1$,可以通过差分的思想来实现。我们可以用树状数组存储每扇门的状态,每次修改时将区间两端加 $1$,查询时求前缀和即可。