AtCoder Beginner Contest 134 D Preparing Boxes
表題通りです。
D Preparing Boxes
問題
問題概要
個の数字が書かれた箱と数列 が与えられる。 の倍数の箱に入っているボールの数の合計の が と一致するようにしたい。ボールの入れ方を答えよ。
考察
後ろから条件を満たすようにボールを入れていく。
例えば、 とすると、 の場合はその倍数が に存在しないので の通りボールを入れれば良い。
次に の場合、 の倍数は しかない。 には よりボールが入っているので、箱3にはボールを入れる必要はない。
このように のときも の範囲で の倍数の箱のボールの数を数えていき帳尻を合わせればよい。
計算量が非常に重要で一見 に感じるが、実際は になり十分高速である。(調和級数で調べると良いらしい)
この問題から得られる知見 前から箱のボールを決めようとすると後ろの状況が未知なので混乱するが、後ろから答えを決めることで1つが決まれば前の箱の状況は一意に求まる。
コード
#include <bits/stdc++.h> using namespace std; #define rep(i,n) for(long long i=0; i<n; i++) int main() { int n; cin >> n; vector<int> a(n), b(n, 0); set<int> st; rep(i, n) cin >> a[i]; for (int i = n; i > 0; --i) { int cnt = 0; for (int j = i + i; j <= n; j += i) { cnt += b[j - 1]; } if (cnt % 2 != a[i-1]) { b[i-1] = 1; st.insert(i); } } cout << st.size() << endl; if (st.size()) { for (auto&& itr : st) { cout << itr << " "; } } }