Quantcast
Channel: プログラミング
Viewing all articles
Browse latest Browse all 8211

【AtCoder】ABC 378 C - Repeating | 茶コーダーが解くAtCoder - Yuulis.log

$
0
0

atcoder.jp

実行時間制限: 2 sec / メモリ制限: 1024 MB / Difficulty: 191

問題概要

長さ  Nの正整数列  Aが与えられるので、以下で定義される長さ  Nの数列  Bを求めよ。

  •  i=1,2,\cdots,Nについて、 A_iと等しい要素が  iの直前に出現した位置を  B_iとする。そのような位置が存在しなければ  B_i=-1とする。

制約

  • 入力はすべて整数。
  •  1 \leq N \leq 2 \times 10^5
  •  1 \leq A_i \leq 10^9

考察

定義通り  i 1から順に増やしていき、  B_iの値を確定させていけばよい。


工夫すべきなのはデータの持ち方、すなわち  A_i = A_j \: (j \lt i)を満たす最大の  jの記憶方法である。  1 \leq A_i \leq 10^9なので、普通にvectorを使うと MLE となってしまう。

そこで、keyをある値  xvalueを「 A_j = xとなる  j \: (1 \leq j \lt i)の中で最大のもの」とするような連想配列 (ここではlast_posとした) を用意する。その上で、以下のようなアルゴリズムにより解くことができる。

  1.  A_iを先頭から見ていく。
  2. 現時点でlast_poskey A_iが含まれているとき
    1.  B_i = \mathrm{last\_pos}_{A_i}とする。
  3. そうでないとき
    1.  \mathrm{last\_pos}_{A_i} = i + 1とする。

コード

#include <bits/stdc++.h>usingnamespacestd;

#define rep(i, start, end) for (auto i = (start); (i) < (end); (i)++)// ======================================== //intmain()
{
    int N;
    cin>> N;
    vector<int> A(N);
    rep(i, 0, N) cin>> A[i];

    vector<int> B(N, -1);
    unordered_map<int, int> last_pos;
    rep(i, 0, N)
    {
        if (last_pos.contains(A[i]))
            B[i] = last_pos[A[i]];

        last_pos[A[i]] = i + 1;
    }

    rep(i, 0, N) cout<< B[i] << " ";
    cout<< endl;

    return0;
}

atcoder.jp

実装時間: 10分


Viewing all articles
Browse latest Browse all 8211

Trending Articles