1 条题解
-
0
方法思路
这道题目可以使用差分数组来高效解决。差分数组是一种常用的技巧,可以将区间更新操作转化为两个点的更新操作。
- 创建一个差分数组
diff
,长度为N+1,初始值全为0 - 对于每次陨石坠落区间[L,R]:
- 将
diff[L]
增加1,表示从位置L开始,每个位置的打击次数增加1 - 将
diff[R+1]
减少1,表示从位置R+1开始,打击次数的增量结束
- 将
- 计算前缀和:从左到右遍历差分数组,得到每个位置的实际打击次数
- 对于每个查询位置x,直接返回对应的前缀和值
代码实现
Java
import java.util.*; import java.io.*; public class Main { public static void main(String[] args) throws IOException { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out)); String[] firstLine = br.readLine().split(" "); int N = Integer.parseInt(firstLine[0]); int M = Integer.parseInt(firstLine[1]); // 读取左边界 String[] leftBounds = br.readLine().split(" "); int[] L = new int[M]; for (int i = 0; i < M; i++) { L[i] = Integer.parseInt(leftBounds[i]); } // 读取右边界 String[] rightBounds = br.readLine().split(" "); int[] R = new int[M]; for (int i = 0; i < M; i++) { R[i] = Integer.parseInt(rightBounds[i]); } // 创建差分数组 int[] diff = new int[N + 2]; // 多一个位置处理R+1 // 处理每次陨石坠落 for (int i = 0; i < M; i++) { diff[L[i]]++; // 区间开始位置增加1 diff[R[i] + 1]--; // 区间结束位置的下一个位置减少1 } // 计算前缀和,得到每个位置的打击次数 int[] hits = new int[N + 1]; for (int i = 0; i <= N; i++) { hits[i] = (i == 0) ? diff[i] : hits[i-1] + diff[i]; } // 处理查询 int Q = Integer.parseInt(br.readLine()); String[] queries = br.readLine().split(" "); StringBuilder sb = new StringBuilder(); for (int i = 0; i < Q; i++) { int x = Integer.parseInt(queries[i]); sb.append(hits[x]); if (i < Q - 1) sb.append(" "); } bw.write(sb.toString()); bw.flush(); } }
Python
def main(): # 读取输入 N, M = map(int, input().split()) L = list(map(int, input().split())) R = list(map(int, input().split())) Q = int(input()) queries = list(map(int, input().split())) # 创建差分数组 diff = [0] * (N + 2) # 处理每次陨石坠落 for i in range(M): diff[L[i]] += 1 # 区间开始位置增加1 diff[R[i] + 1] -= 1 # 区间结束位置的下一个位置减少1 # 计算前缀和,得到每个位置的打击次数 hits = [0] * (N + 1) for i in range(N + 1): hits[i] = diff[i] if i == 0 else hits[i-1] + diff[i] # 处理查询并输出结果 results = [hits[x] for x in queries] print(' '.join(map(str, results))) if __name__ == "__main__": main()
C++
#include <iostream> #include <vector> using namespace std; int main() { ios_base::sync_with_stdio(false); cin.tie(NULL); int N, M; cin >> N >> M; // 读取左边界 vector<int> L(M); for (int i = 0; i < M; i++) { cin >> L[i]; } // 读取右边界 vector<int> R(M); for (int i = 0; i < M; i++) { cin >> R[i]; } // 创建差分数组 vector<int> diff(N + 2, 0); // 处理每次陨石坠落 for (int i = 0; i < M; i++) { diff[L[i]]++; // 区间开始位置增加1 diff[R[i] + 1]--; // 区间结束位置的下一个位置减少1 } // 计算前缀和,得到每个位置的打击次数 vector<int> hits(N + 1); hits[0] = diff[0]; for (int i = 1; i <= N; i++) { hits[i] = hits[i-1] + diff[i]; } // 处理查询 int Q; cin >> Q; for (int i = 0; i < Q; i++) { int x; cin >> x; cout << hits[x]; if (i < Q - 1) cout << " "; } cout << endl; return 0; }
- 创建一个差分数组
- 1
信息
- ID
- 59
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 5
- 标签
- 递交数
- 1
- 已通过
- 1
- 上传者