Official
A - 成績管理システム / Grade Management System Editorial
by
A - 成績管理システム / Grade Management System Editorial
by
MMNMM
初心者の方へ
- AtCoder をはじめたばかりで何をしたらよいか分からない方は、まずは practice contest の問題A「Welcome to AtCoder」を解いてみてください。基本的な入出力の方法が載っています。
- また、プログラミングコンテストの問題に慣れていない方は、AtCoder Beginners Selection の問題をいくつか解いてみることをおすすめします。
- C++入門 AtCoder Programming Guide for beginners (APG4b) は、競技プログラミングのための C++ 入門用コンテンツです。
- Python入門 AtCoder Programming Guide for beginners (APG4bPython) は、競技プログラミングのための Python 入門用コンテンツです。
各生徒のスコアを並べた配列を使い、種類 2, 3 のクエリを適切に for 文などを使って処理することで、それぞれのクエリは \(O(N)\) 時間で処理することができます。
全体で \(O(QN)\) 時間で解くことができ、この問題の制約のもとで十分高速です。
実装例は以下のようになります。
#include <iostream>
#include <vector>
using namespace std;
int main() {
int N;
cin >> N;
// N 人のスコアを管理する
// はじめはすべて 0
vector<long> score(N);
int Q;
cin >> Q;
for (int q = 0; q < Q; ++q) { // Q 回クエリを処理する
int t;
cin >> t;
if (t == 1) { // 種類 1
int a, b, v;
cin >> a >> b >> v;
--a; // 0-indexed にする
--b;
score[a] -= v; // a から v 減らして
score[b] += v; // b を v 増やす
} else if (t == 2) { // 種類 2
int x, l, r;
cin >> x >> l >> r;
--x; // 0-indexed にする
--l; // l, r を 0-indexed 右半開区間にする
int ans = 0;
for (int i = l; i < r; ++i) { // [l, r) のうち
ans += score[i] > score[x]; // スコアが x より大きい人を数える
}
cout << ans << endl;
} else { // 種類 3
int l, r, v;
cin >> l >> r >> v;
--l; // l, r を 0-indexed 右半開区間にする
for (int i = l; i < r; ++i) { // [l, r) のスコアを
score[i] += v; // v 増やす
}
}
}
return 0;
}
N, Q = map(int, input().split())
# N 人のスコアを管理する
# はじめはすべて 0
score = [0 for _ in range(N)]
for q in range(Q): # Q 回クエリを処理する
t, x, y, z = map(int, input().split())
if t == 1: # 種類 1
x -= 1 # 0-indexed にする
y -= 1
score[x] -= z # x から z 減らして
score[y] += z # y を z 増やす
elif t == 2: # 種類 2
x -= 1 # 0-indexed にする
y -= 1 # y, z を 0-indexed 右半開区間にする
ans = 0
for i in range(y, z): # [y, z) のうち
if score[i] > score[x]: # スコアが x より大きい人を数える
ans += 1
print(ans)
else: # 種類 3
x -= 1 # x, y を 0-indexed 右半開区間にする
for i in range(x, y): # [x, y) のスコアを
score[i] += z # z 増やす
posted:
last update:
