Submission #73367027
Source Code Expand
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ld = long double;
using vll = vector<ll>;
using vvll = vector<vector<ll>>;
using vst = vector<string>;
using vvst = vector<vector<string>>;
using vbool = vector<bool>;
using vvbool = vector<vector<bool>>;
using vch = vector<char>;
using vvch = vector<vector<char>>;
using pll = pair<ll, ll>;
using stll = stack<ll>;
using stst = stack<string>;
using setll = set<ll>;
using sets = set<string>;
using mapll = map<ll, ll>;
const ll INF = 1e18;
const ll MOD = 998244353; // 問題に合わせて 1000000007 に変更
const double PI = acos(-1);
const ll dx[] = {0, 1, 0, -1};
const ll dy[] = {1, 0, -1, 0};
#define rep(i, n) for(ll i = 0; i < (ll)(n); i++) // 0からn未満の繰り返し
#define rep2(i, a, n) for(ll i = a; i < (ll)(n); i++) // aからn未満の繰り返し
#define rrep(i, n) for(ll i = (ll)(n) - 1; i >= 0; i--) // n-1から0以上の繰り返し
#define rrep2(i, a, n) for(ll i = (ll)(n) - 1; i >= a; i--) // n-1からa以上の繰り返し
#define all(v) (v).begin(), (v).end() // 小さい順にソート
#define rall(v) (v).rbegin(), (v).rend() //大きい順にソート
#define Yes(b) cout << ((b) ? "Yes" : "No") << endl
// 最小値・最大値の更新 (更新されたらtrueを返す)
template<class T> inline bool chmin(T& a, T b) { if (a > b) { a = b; return true; } return false; }
template<class T> inline bool chmax(T& a, T b) { if (a < b) { a = b; return true; } return false; }
// 自動でMODをとる構造体
struct mint {
ll x;
// コンストラクタ
mint(ll x = 0) : x((x % MOD + MOD) % MOD) {}
// 単項演算子 -
mint operator-() const { return mint(-x); }
// 加算・減算・乗算・除算 (代入演算子)
mint& operator+=(const mint& a) {
if ((x += a.x) >= MOD) x -= MOD;
return *this;
}
mint& operator-=(const mint& a) {
if ((x += MOD - a.x) >= MOD) x -= MOD;
return *this;
}
mint& operator*=(const mint& a) {
(x *= a.x) %= MOD;
return *this;
}
mint& operator/=(const mint& a) {
return *this *= a.inv();
}
// インクリメント・デクリメント
mint& operator++() {
if (++x >= MOD) x -= MOD;
return *this;
}
mint operator++(int) {
mint res = *this;
++*this;
return res;
}
mint& operator--() {
if (x == 0) x = MOD;
x--;
return *this;
}
mint operator--(int) {
mint res = *this;
--*this;
return res;
}
// 累乗
mint pow(ll t) const {
if (!t) return 1;
mint a = pow(t >> 1);
a *= a;
if (t & 1) a *= *this;
return a;
}
// 逆元
mint inv() const {
return pow(MOD - 2);
}
// フレンド関数: ll との計算 (左右どちらでも可)
friend mint operator+(const mint& a, const mint& b) { return mint(a) += b; }
friend mint operator-(const mint& a, const mint& b) { return mint(a) -= b; }
friend mint operator*(const mint& a, const mint& b) { return mint(a) *= b; }
friend mint operator/(const mint& a, const mint& b) { return mint(a) /= b; }
// 比較演算子 (std::set や std::map で使用可能)
// ll と比較する場合も、mod を取った後の値で比較されることに注意
friend bool operator==(const mint& a, const mint& b) { return a.x == b.x; }
friend bool operator!=(const mint& a, const mint& b) { return a.x != b.x; }
friend bool operator<(const mint& a, const mint& b) { return a.x < b.x; }
friend bool operator>(const mint& a, const mint& b) { return a.x > b.x; }
friend bool operator<=(const mint& a, const mint& b) { return a.x <= b.x; }
friend bool operator>=(const mint& a, const mint& b) { return a.x >= b.x; }
// 入出力
friend istream& operator>>(istream& is, mint& a) { return is >> a.x; }
friend ostream& operator<<(ostream& os, const mint& a) { return os << a.x; }
};
// 最大公約数
ll gcd(ll a, ll b) { return b ? gcd(b, a % b) : a; }
// 最小公倍数 (オーバーフローに注意)
ll lcm(ll a, ll b) { return a / gcd(a, b) * b; }
// 素因数分解 (O(sqrt(N)))
// 返り値: {素数, 指数} の map
mapll prime_factor(ll n) {
mapll ret;
for (ll i = 2; i * i <= n; i++) {
while (n % i == 0) {
ret[i]++;
n /= i;
}
}
if (n != 1) ret[n] = 1;
return ret;
}
// 組み合わせ計算 (nCr)
ll conbi(ll n, ll r) {
if (r < 0 || r > n) return 0;
if (r > n / 2) r = n - r;
ll res = 1;
for (ll i = 1; i <= r; ++i) {
res = res * (n - i + 1) / i;
}
return res;
}
// 配列の中身を表示
template <typename T>
void print_vec(const T& v) {
for (const auto& x : v) cout << x << " ";
cout << endl;
}
// ベクトルの入力: cin >> v; で動く
template <typename T>
istream& operator>>(istream& is, vector<T>& v) {
for (T& in : v) is >> in;
return is;
}
// ベクトルの出力: cout << v; で動く (スペース区切り)
template <typename T>
ostream& operator<<(ostream& os, const vector<T>& v) {
for (ll i = 0; i < (int)v.size(); i++) {
os << v[i] << (i + 1 != (int)v.size() ? " " : "");
}
return os;
}
// 2次元配列の cout 出力対応
template <typename T>
ostream& operator<<(ostream& os, const vector<vector<T>>& v) {
for (ll i = 0; i < v.size(); i++) {
for (ll j = 0; j < v[i].size(); j++) {
os << v[i][j] << (j == v[i].size() - 1 ? "" : " ");
}
if (i != v.size() - 1) os << endl; // 最後の行以外は改行
}
return os;
}
// セグメント木の作成
template <typename T>
class SegmentTree {
// 演算関数の型エイリアス
using F = function<T(T, T)>;
ll size; // 葉の数 (2のべき乗)
vector<T> tree; // データを格納する配列
F op; // 区間クエリで使う演算 (min, max, sumなど)
T e; // 単位元 (演算に影響しない値)
public:
// コンストラクタ
SegmentTree(const vector<T>& v, F _op, T _e) : op(_op), e(_e) {
ll n = v.size();
size = 1;
while (size < n) size *= 2; // 2のべき乗にする
tree.assign(2 * size, e); // 単位元で初期化
// 葉(最下段)に値をセット
for (ll i = 0; i < n; i++) {
tree[size + i] = v[i];
}
// 親に向かって構築 (1-indexed: 根は1)
for (ll i = size - 1; i >= 1; i--) {
tree[i] = op(tree[2 * i], tree[2 * i + 1]);
}
}
// 1点更新: index番目の値をxに変更
void update(ll index, T x) {
index += size; // 葉のノード番号に変換
tree[index] = x;
// 親に向かって更新
while (index > 1) {
index /= 2;
tree[index] = op(tree[2 * index], tree[2 * index + 1]);
}
}
// 区間取得: [l, r) の演算結果を求める (半開区間)
T query(ll l, ll r) {
T res_l = e; // 左側の累積結果
T res_r = e; // 右側の累積結果
l += size; // 葉のインデックスへ
r += size;
while (l < r) {
// 左端が右側の子なら、それを採用して右へシフト
if (l % 2 == 1) {
res_l = op(res_l, tree[l]);
l++;
}
// 右端が右側の子なら、一つ左(左側の子)を採用
if (r % 2 == 1) {
r--;
res_r = op(tree[r], res_r);
}
l /= 2;
r /= 2;
}
return op(res_l, res_r);
}
// 特定の要素を取得 (デバッグ用など)
T get(ll index) {
return tree[size + index];
}
// セグメント木上の二分探索 (O(log N))
// [l, n) の範囲で、check( query(l, i+1) ) が true になる「最初のインデックス i」を返す
// 見つからない場合は -1 を返す
// check: 条件判定関数 (例: [](T val){ return val >= 10; })
ll find_first(ll l, const function<bool(T)>& check) {
if (l < 0 || l >= size) return -1;
T acc = e; // それまでの累積値
return find_first_recurse(l, size, 1, 0, size, check, acc);
}
private:
// 再帰用関数
// a, b: 探索したい範囲 [a, b) (今回は [l, size))
// k: 現在のノード番号
// l, r: 現在のノードがカバーする範囲 [l, r)
// check: 判定関数
// acc: これまでの累積値 (参照渡しで更新していく)
ll find_first_recurse(ll a, ll b, ll k, ll l, ll r, const function<bool(T)>& check, T& acc) {
// 1. 範囲外なら無視
if (r <= a || b <= l) return -1;
// 2. このノードの値を含めても条件を満たさないなら、
// この部分木には答えがないので、値をaccに統合してスキップ
if (check(op(acc, tree[k])) == false) {
acc = op(acc, tree[k]);
return -1;
}
// 3. 葉に到達した場合、条件を満たす(2で弾かれていないため)のでインデックスを返す
if (k >= size) {
return k - size;
}
// 4. 子ノードを探索(左 -> 右 の順)
ll vl = find_first_recurse(a, b, 2 * k, l, (l + r) / 2, check, acc);
if (vl != -1) return vl; // 左で見つかればそれを返す
return find_first_recurse(a, b, 2 * k + 1, (l + r) / 2, r, check, acc);
}
};
/*
区間和の宣言
SegmentTree<long long> st_sum(v, [](long long a, long long b){ return a + b; }, 0);
区間最小値の宣言
SegmentTree<long long> st_min(v, [](long long a, long long b){ return min(a, b); }, INF);
*/
// ユニオンファインド
struct UnionFind {
vector<int> par; // 親の番号
// コンストラクタ
UnionFind(ll N) : par(N) {
for(ll i = 0; i < N; i++) par[i] = -1; // -1なら根。絶対値はサイズ
}
// 根を求める (経路圧縮)
ll root(ll x) {
if (par[x] < 0) return x;
return par[x] = root(par[x]);
}
// x と y を結合する
void unite(ll x, ll y) {
ll rx = root(x);
ll ry = root(y);
if (rx == ry) return; // 同じグループなら何もしない
// サイズが大きい方にマージする (高速化)
if (par[rx] > par[ry]) swap(rx, ry);
par[rx] += par[ry]; // サイズを加算
par[ry] = rx; // ryの親をrxにする
}
// x と y が同じグループか判定
bool same(ll x, ll y) {
return root(x) == root(y);
}
// x が属するグループのサイズ
ll size(ll x) {
return -par[root(x)];
}
};
/*
UnionFindの使い方
UnionFind uf(N);
uf.unite(0, 1); // 0と1をつなぐ
if(uf.same(0, 2)) { ... } // 判定
*/
// string型をvll型に変換
// 第一引数は文字列, 第二引数は底上げする定数(初期では a = 0と扱う)
vll string_to_vll(string s, ll up = 0){
ll n = size(s);
vll result(n);
rep(i, n){
result[i] = s[i] - 'a' + up;
}
return result;
}
// vll型をstring型に変換。
// 第一引数はvll, 第二引数は底を低くする定数(初期では a = 0と扱う)
string vll_to_string(vll v, ll down = 0){
ll n = v.size();
string s = "";
s.reserve(n);
rep(i, n){
// 数値に対応する文字に変換 ('a' を基準にする場合)
// 例: 0 -> 'a', 1 -> 'b'
char c = 'a' + (v[i] - down);
s += c;
}
return s;
}
// index が条件を満たすかどうか
bool isOK(ll &index, ll &key, vll &a) {
if (a[index] >= key) return true;
else return false;
}
// めぐる式二分探索
ll binary_search(ll &key, vll &a) {
ll ng = -1; //「index = 0」が条件を満たすこともあるので、初期値は -1
ll ok = (ll)a.size(); // 「index = a.size()-1」が条件を満たさないこともあるので、初期値は a.size()
// ok と ng のどちらが大きいかわからないことを考慮
while (abs(ok - ng) > 1) {
ll mid = (ok + ng) / 2;
if (isOK(mid, key, a)) ok = mid;
else ng = mid;
}
return ok;
}
// --------------------------------------------------------
// ダイクストラ法
// graph: 隣接リスト。graph[u] = { {v, cost}, ... }
// start: 始点
// dist: 距離を格納する配列 (参照渡しで更新)
void dijkstra(const vector<vector<pll>>& graph, ll start, vll& dist) {
dist.assign(graph.size(), INF);
dist[start] = 0;
priority_queue<pll, vector<pll>, greater<pll>> pq;
pq.push({0, start}); // {cost, v}
while (!pq.empty()) {
auto [d, v] = pq.top();
pq.pop();
if (d > dist[v]) continue;
for (auto& edge : graph[v]) {
ll to = edge.first;
ll cost = edge.second;
if (chmin(dist[to], dist[v] + cost)) {
pq.push({dist[to], to});
}
}
}
}
/*
使い方:
ll N, M; cin >> N >> M;
vector<vector<pll>> G(N);
rep(i, M) {
ll u, v, w; cin >> u >> v >> w;
u--; v--; // 0-indexed
G[u].push_back({v, w});
G[v].push_back({u, w}); // 無向グラフの場合
}
vll dist;
dijkstra(G, 0, dist);
*/
// -----------------------------------------------------------
// ワーシャルフロイド法
// dist[i][j] : iからjへの最短距離。初期値はINF (ただし dist[i][i] = 0)
void warshall_floyd(vvll& dist) {
ll n = dist.size();
rep(k, n) {
rep(i, n) {
rep(j, n) {
if (dist[i][k] != INF && dist[k][j] != INF) {
chmin(dist[i][j], dist[i][k] + dist[k][j]);
}
}
}
}
}
// ------------------------------------------------------------
// クラスカル法用の辺構造体
struct Edge {
ll u, v, cost;
// コストの小さい順にソートするための比較演算子
bool operator<(const Edge& o) const {
return cost < o.cost;
}
};
// クラスカル法
// N: 頂点数
// edges: 辺のリスト (u, v, cost)
// 返り値: 最小全域木の総コスト
ll kruskal(int N, vector<Edge>& edges) {
sort(all(edges)); // 辺をコスト順にソート
UnionFind uf(N); // 以前のテンプレートのUnionFindを使用
ll sum = 0;
for (const auto& e : edges) {
if (!uf.same(e.u, e.v)) {
uf.unite(e.u, e.v);
sum += e.cost;
}
}
return sum;
}
/* 使い方:
ll N, M; cin >> N >> M;
vector<Edge> edges;
rep(i, M) {
ll u, v, w; cin >> u >> v >> w;
u--; v--; // 0-indexed
edges.push_back({u, v, w});
}
cout << kruskal(N, edges) << endl;
*/
// ------------------------------------------------------------
// プリム法
// graph: 隣接リスト。graph[u] = { {v, cost}, ... }
// 返り値: 最小全域木の総コスト
// ※頂点0を含む連結成分のMSTを求めます
ll prim(const vector<vector<pll>>& graph) {
ll N = graph.size();
ll sum = 0;
vector<bool> visited(N, false);
// {cost, v} のペア。コストが小さい順に取り出す
priority_queue<pll, vector<pll>, greater<pll>> pq;
// 頂点0からスタート (コスト0)
pq.push({0, 0});
while (!pq.empty()) {
auto [cost, u] = pq.top();
pq.pop();
// 既に木に含まれているならスキップ
if (visited[u]) continue;
// 木に含める
visited[u] = true;
sum += cost;
// 隣接する頂点を候補に追加
for (auto& edge : graph[u]) {
ll v = edge.first;
ll w = edge.second;
if (!visited[v]) {
pq.push({w, v});
}
}
}
return sum;
}
/* 使い方:
ll N, M; cin >> N >> M;
vector<vector<pll>> G(N);
rep(i, M) {
ll u, v, w; cin >> u >> v >> w;
u--; v--;
G[u].push_back({v, w});
G[v].push_back({u, w}); // 無向グラフ
}
cout << prim(G) << endl;
*/
// -----------------------------------------------------------
// 座標圧縮
// 元の値を座圧後の値(0-indexed)に変換する
// vals: 重複ありの座標リスト
// 返り値: 圧縮されたリスト (これを使って binary_search する)
template <typename T>
vector<T> compress(vector<T> &vals) {
sort(all(vals));
vals.erase(unique(all(vals)), vals.end());
return vals;
}
// 値 x が座圧後の何番目かを返す (lower_bound)
template <typename T>
ll get_pos(const vector<T> &vals, T x) {
return lower_bound(all(vals), x) - vals.begin();
}
/*
使い方:
vll A = {100, 2, 100, 50, 2};
vll vals = A; // コピー
compress(vals); // vals は {2, 50, 100} になる
rep(i, N) {
cout << get_pos(vals, A[i]) << " "; // 2 -> 1, 0, 2, 1, 0
}
*/
// -------------------------------------------------------
// トポロジカルソート
// G: グラフ, N: 頂点数
// 返り値: ソートされた頂点リスト (閉路がある場合は空のvectorを返す)
vll topological_sort(const vector<vll> &G, ll N) {
vll res;
vll indegree(N, 0);
rep(i, N) for (ll next : G[i]) indegree[next]++;
queue<ll> q;
rep(i, N) if (indegree[i] == 0) q.push(i);
while (!q.empty()) {
ll v = q.front(); q.pop();
res.push_back(v);
for (ll next : G[v]) {
indegree[next]--;
if (indegree[next] == 0) q.push(next);
}
}
if (res.size() != (size_t)N) return {};
return res;
}
// --------------------------------------------------------
// 幾何ライブラリ (2次元)
struct Point {
double x, y;
Point(double x=0, double y=0): x(x), y(y) {}
// ベクトル演算
Point operator+(const Point& a) const { return Point(x+a.x, y+a.y); }
Point operator-(const Point& a) const { return Point(x-a.x, y-a.y); }
Point operator*(double k) const { return Point(x*k, y*k); }
// ノルム (大きさの2乗)
double norm() const { return x*x + y*y; }
// 大きさ
double abs() const { return sqrt(norm()); }
// 内積 (dot product)
double dot(const Point& a) const { return x*a.x + y*a.y; }
// 外積 (cross product) -> 平行四辺形の面積・回転方向判定
double cross(const Point& a) const { return x*a.y - y*a.x; }
// 比較演算子 (sort用: x座標優先)
bool operator<(const Point& a) const {
return x != a.x ? x < a.x : y < a.y;
}
};
// 偏角ソートなどで使う出力
ostream& operator<<(ostream& os, const Point& p) {
return os << "(" << p.x << ", " << p.y << ")";
}
// ランレングス圧縮 (Run-Length Encoding)
// 文字列 s を受け取り、{文字, 連続回数} のペアの配列を返す
// 例: "AABBBC" -> {{'A', 2}, {'B', 3}, {'C', 1}}
vector<pair<char, int>> rle(const string& s) {
vector<pair<char, int>> res;
ll n = s.size();
for (ll i = 0; i < n;) {
ll j = i + 1;
while (j < n && s[i] == s[j]) j++;
res.push_back({s[i], j - i});
i = j;
}
return res;
}
// 数列用 (vector<long long> など) のオーバーロード
// 例: {1, 1, 2, 2, 2} -> {{1, 2}, {2, 3}}
template <typename T>
vector<pair<T, int>> rle(const vector<T>& v) {
vector<pair<T, int>> res;
ll n = v.size();
for (ll i = 0; i < n;) {
ll j = i + 1;
while (j < n && v[i] == v[j]) j++;
res.push_back({v[i], j - i});
i = j;
}
return res;
}
/*
-------- アルゴリズムリスト -------------
----------------------------------------------
bit全探索
rep(bit, 1<<N){ // 2のN乗を表す
ll A=0, B=0;
rep(i, N){
if(bit>>i & 1) A += K[i]; // 各ビットが0 or 1かを判定
else B += K[i];
}
}
--------------------------------------------------
vvll s;
//dfs (INF = wall)
void dfs(ll x, ll y, ll H, ll W, ll D){
s[y][x] = D;
rep(i, 4){
ll nx = x + dx[i], ny = y + dy[i];
if(ny < 0 || H <= ny || nx < 0 || W <= nx) continue;
if(s[ny][nx] != INF && D-1 > s[ny][nx]){
dfs(nx, ny, H, W, D-1);
}
}
}
// bfs
queue<pair<ll, ll>> q;
rep(i, H){
string s_temp;
cin >> s_temp;
rep(j, W){
if(s_temp[j] == 'H'){
s[i][j] = D+1;
q.push({i, j}); // 要素の挿入
}
else if(s_temp[j] == '#') s[i][j] = INF;
}
}
while(!q.empty()){
ll y = q.front().first, x = q.front().second; // 先端要素の取得
q.pop(); // 先端要素を排除
rep(i, 4){
ll nx = x + dx[i], ny = y + dy[i];
if(ny < 0 || H <= ny || nx < 0 || W <= nx) continue;
if(s[ny][nx] != INF && s[y][x]-1 > s[ny][nx]){
q.push({ny, nx});
s[ny][nx] = s[y][x] - 1;
}
}
}
// 迷路BFS
// H, W, start_y, start_x, Grid(S) は定義済みとする
vvll dist(H, vll(W, -1));
queue<pair<ll, ll>> q;
dist[sy][sx] = 0;
q.push({sy, sx});
while (!q.empty()) {
auto [y, x] = q.front(); q.pop();
// 終了条件 (ゴールについた)
if (y == gy && x == gx) break;
rep(i, 4) {
ll ny = y + dy[i];
ll nx = x + dx[i];
// 範囲外・壁・訪問済み チェック
if (ny < 0 || ny >= H || nx < 0 || nx >= W) continue;
if (S[ny][nx] == '#') continue;
if (dist[ny][nx] != -1) continue;
dist[ny][nx] = dist[y][x] + 1;
q.push({ny, nx});
}
}
*/
/*
--------- 忘れそうな文法リスト -----------
グローバル変数で定義したvectorの中身を後から決める方法
vvll strength_list; //グローバル変数
strength_list.resize(N, vll(0)); //main関数内
-------------------------------------------
辞書(map)の使い方
mapll dict; //定義
dict.insert{(key, value}) // 挿入法一つ目
dist[key] = value // 挿入法二つ目
dict.erase(key) // 要素の削除法
Yes(dict.count(key)) // 検索法一つ目
Yes(dict.contains(key)) // 検索法二つ目
ll min_val = *dict.begin(); 最小値の取得方法
ll max_val = *dict.rbegin(); // 最大値の取得方法
for(auto temp : dict){
cout << temp.first << " " << temp.second << endl // 全要素の表示
}
---------------------------------------------
集合(set)の使い方
setll st;
st.insert(num) // 挿入法
st.count(num) // 検索法一つ目
st.contains(num) // 検索法二つ目
ll min_val = *st.begin(); 最小値の取得方法
ll max_val = *st.rbegin(); // 最大値の取得方法
ll target = *st.lower_bound(num); // 二分探索(num以上の最小の要素) (※endチェック必須!)
ll target = *st.upper_bound(num); // 二分探索(numを超えるの最小の要素)
// 二分探索 (※endチェック必須!)
auto it = st.lower_bound(num); // num以上のイテレータ
if (it != st.end()) {
ll val = *it; // ここで初めて値を取り出す
} else {
// num以上の値は存在しない場合の処理
}
st.erase(num) // 要素の削除法
while(!st.empty()){ // 破壊的操作をする場合
auto temp = A.front();
cout << temp.first << " " << temp.second << endl // 全要素の表示
st.pop();
}
for(auto temp : st){ // 破壊的操作をしない場合
cout << temp.first << " " << temp.second << endl // 全要素の表示
}
A.size() // 濃度の表示
二分探索 or 最大値 or 最小値 => set, multiset
自分でハッシュ関数を定義する場合 => unordered_set (平均O(1), 最悪O(N))
---------------------------------------------
vectorの二分探索
vll v = {1, 2, 5, 9, 20, 100};
ll key = 5;
// lower_bound (v[i] >= key と初めてなるようなイテレータを返す)
auto it_lower = lower_bound(all(v), key);
if (it_lower != v.end()) {
cout << *it_lower << endl; // 値の表示(5)
} else {
cout << "key以上の要素は存在しません" << endl;
}
cout << it_lower - v.begin() << endl; // 先頭からの距離を表示(2, 0-origin)
cout << v.end() - it_lower << endl; // 末尾までの距離を表示(4)
it_lower - v.begin() でvの要素でkey未満の値の個数が分かる。
v.end() - it_lower でvの要素でkey以上の値の個数が分かる。
// upper_bound (v[i] > key と初めてなるようなイテレータを返す)
auto it_upper = upper_bound(all(v), key);
if (it_upper != v.end()) {
cout << *it_upper << endl; // 値の表示(9)
} else {
cout << "key以上の要素は存在しません" << endl;
}
cout << it_upper - v.begin() << endl; // 先頭からの距離を表示(3, 0-origin)
cout << v.end() - it_upper << endl; // 末尾までの距離を表示(3)
it_upper - v.begin() でvの要素でkey以下の値の個数が分かる。
v.end() - it_upper でvの要素でkeyを超えるの値の個数が分かる。
it_upper - it_lower でkeyの値の要素の個数を求めることが可能。
--------------------------------------------------------
*/
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
cout << fixed << setprecision(15);
// --- ここからコードを書く ---
ll N, L, W, result = 0;
cin >> N >> L >> W;
rep(i, N){
ll D;
cin >> D;
if(L - W <= D && D <= L + W){
result++;
}
}
cout << (result) << endl;;
// ---------------------------
return 0;
}
Submission Info
| Submission Time |
|
| Task |
A - Target Shooting Game |
| User |
RumineMocha |
| Language |
C++23 (GCC 15.2.0) |
| Score |
200 |
| Code Size |
26515 Byte |
| Status |
AC |
| Exec Time |
11 ms |
| Memory |
3620 KiB |
Judge Result
| Set Name |
Sample |
All |
| Score / Max Score |
0 / 0 |
200 / 200 |
| Status |
|
|
| Set Name |
Test Cases |
| Sample |
sample01.txt, sample02.txt, sample03.txt, sample04.txt, sample05.txt |
| All |
sample01.txt, sample02.txt, sample03.txt, sample04.txt, sample05.txt, in01.txt, in02.txt, in03.txt, in04.txt, in05.txt, in06.txt, in07.txt, in08.txt, in09.txt, in10.txt, in11.txt, in12.txt, in13.txt, in14.txt, in15.txt, in16.txt, in17.txt, in18.txt, in19.txt, in20.txt, in21.txt, in22.txt, in23.txt, in24.txt, in25.txt, in26.txt, in27.txt, in28.txt, in29.txt, in30.txt, in31.txt, in32.txt, in33.txt, in34.txt, in35.txt, in36.txt, in37.txt, in38.txt, in39.txt, in40.txt, in41.txt, in42.txt, in43.txt, in44.txt, in45.txt, in46.txt, in47.txt, in48.txt, in49.txt, in50.txt, in51.txt, in52.txt, in53.txt, in54.txt, in55.txt, in56.txt, in57.txt, in58.txt, in59.txt, in60.txt, in61.txt, in62.txt, in63.txt |
| Case Name |
Status |
Exec Time |
Memory |
| in01.txt |
AC |
1 ms |
3476 KiB |
| in02.txt |
AC |
1 ms |
3456 KiB |
| in03.txt |
AC |
1 ms |
3500 KiB |
| in04.txt |
AC |
1 ms |
3456 KiB |
| in05.txt |
AC |
1 ms |
3508 KiB |
| in06.txt |
AC |
1 ms |
3492 KiB |
| in07.txt |
AC |
1 ms |
3620 KiB |
| in08.txt |
AC |
8 ms |
3496 KiB |
| in09.txt |
AC |
10 ms |
3528 KiB |
| in10.txt |
AC |
10 ms |
3528 KiB |
| in11.txt |
AC |
9 ms |
3544 KiB |
| in12.txt |
AC |
9 ms |
3524 KiB |
| in13.txt |
AC |
9 ms |
3544 KiB |
| in14.txt |
AC |
10 ms |
3528 KiB |
| in15.txt |
AC |
10 ms |
3552 KiB |
| in16.txt |
AC |
1 ms |
3536 KiB |
| in17.txt |
AC |
11 ms |
3500 KiB |
| in18.txt |
AC |
9 ms |
3540 KiB |
| in19.txt |
AC |
9 ms |
3500 KiB |
| in20.txt |
AC |
8 ms |
3484 KiB |
| in21.txt |
AC |
10 ms |
3620 KiB |
| in22.txt |
AC |
9 ms |
3508 KiB |
| in23.txt |
AC |
9 ms |
3500 KiB |
| in24.txt |
AC |
8 ms |
3536 KiB |
| in25.txt |
AC |
1 ms |
3592 KiB |
| in26.txt |
AC |
1 ms |
3500 KiB |
| in27.txt |
AC |
1 ms |
3508 KiB |
| in28.txt |
AC |
1 ms |
3528 KiB |
| in29.txt |
AC |
1 ms |
3528 KiB |
| in30.txt |
AC |
1 ms |
3508 KiB |
| in31.txt |
AC |
1 ms |
3528 KiB |
| in32.txt |
AC |
1 ms |
3552 KiB |
| in33.txt |
AC |
1 ms |
3492 KiB |
| in34.txt |
AC |
1 ms |
3528 KiB |
| in35.txt |
AC |
1 ms |
3456 KiB |
| in36.txt |
AC |
1 ms |
3500 KiB |
| in37.txt |
AC |
10 ms |
3420 KiB |
| in38.txt |
AC |
9 ms |
3528 KiB |
| in39.txt |
AC |
9 ms |
3476 KiB |
| in40.txt |
AC |
9 ms |
3476 KiB |
| in41.txt |
AC |
9 ms |
3456 KiB |
| in42.txt |
AC |
9 ms |
3528 KiB |
| in43.txt |
AC |
1 ms |
3516 KiB |
| in44.txt |
AC |
10 ms |
3516 KiB |
| in45.txt |
AC |
9 ms |
3492 KiB |
| in46.txt |
AC |
10 ms |
3568 KiB |
| in47.txt |
AC |
10 ms |
3472 KiB |
| in48.txt |
AC |
9 ms |
3560 KiB |
| in49.txt |
AC |
1 ms |
3476 KiB |
| in50.txt |
AC |
1 ms |
3544 KiB |
| in51.txt |
AC |
1 ms |
3620 KiB |
| in52.txt |
AC |
1 ms |
3528 KiB |
| in53.txt |
AC |
1 ms |
3484 KiB |
| in54.txt |
AC |
1 ms |
3552 KiB |
| in55.txt |
AC |
1 ms |
3484 KiB |
| in56.txt |
AC |
1 ms |
3484 KiB |
| in57.txt |
AC |
1 ms |
3536 KiB |
| in58.txt |
AC |
1 ms |
3536 KiB |
| in59.txt |
AC |
1 ms |
3492 KiB |
| in60.txt |
AC |
1 ms |
3544 KiB |
| in61.txt |
AC |
1 ms |
3484 KiB |
| in62.txt |
AC |
1 ms |
3484 KiB |
| in63.txt |
AC |
1 ms |
3568 KiB |
| sample01.txt |
AC |
1 ms |
3456 KiB |
| sample02.txt |
AC |
1 ms |
3524 KiB |
| sample03.txt |
AC |
1 ms |
3500 KiB |
| sample04.txt |
AC |
1 ms |
3380 KiB |
| sample05.txt |
AC |
1 ms |
3592 KiB |