【AtCoder】ABC 467 C - Adjacent Sums (easy)

C - Adjacent Sums (easy)atcoder.jp favicon

実行時間制限: 2 sec / メモリ制限: 1024 MiB / Difficulty: 608 / NoviSteps: 2Q / 配点: 300 点

問題概要

00 以上 M1M-1 以下の整数からなる整数列 A=(A1,A2,,AN),B=(B1,B2,,BN1)A=(A_1,A_2,\dots,A_N), \, B=(B_1,B_2,\dots,B_{N-1}) が与えられる。

AA に対して以下の操作を好きな回数行う。

  • 11 以上 NN 以下の整数 ii11 つ選び、AiA_i11 を加える。

以下の条件を満たすようにするために必要な操作回数の最小値を求めよ。 なお、問題の制約下では、必ず条件を満たすようにできることが証明できる。

  • i=1,2,,N1i=1,2,\dots,N-1 について、Ai+Ai+1A_i+A_{i+1}MM で割った余りは BiB_i に等しい。

制約

  • 2N2×1052 \leq N \leq 2 \times 10^5
  • M=2M=2
  • 0AiM10 \leq A_i \leq M-1
  • 0BiM10 \leq B_i \leq M-1
  • 入力される値はすべて整数

考察

M=2M = 2 なので、 AiA_i0011 のいずれかであり、これはビット列とみなしてよい。

操作後のビット列を xix_i として、条件を満たすためには、xi+xi+1Bi(mod2)x_i + x_{i+1} \equiv B_i \pmod{2} が成り立つ必要がある。

これは、 XOR を使うと以下のように書き直せる。

xixi+1=Bi    xi+1=xiBix_i \oplus x_{i+1} = B_i \iff x_{i+1} = x_i \oplus B_i

つまり、最初のビット x1x_1 を決めると、残りの N1N-1 個のビットは一意に決まる


元の AiA_i が取り得る値は 0011 なので、 ii 番目の要素に対する操作回数は、

  • AixiA_i \neq x_i の場合は 11
  • Ai=xiA_i = x_i の場合は 00

である。 22 回以上余分に加えると偶奇は同じまま操作回数だけ増えるので、各要素への操作は高々 11 回としてよい。

したがって、最初のビット x1x_100 とした場合と 11 とした場合の両方を試して、操作回数の合計が少ない方を選べばよい。

実装例

CPP
1.#include <bits/stdc++.h>
2.using namespace std;
3.
4.#define rep(i, start, end) for (auto i = (start); (i) < (end); (i)++)
5.
6.// ======================================== //
7.
8.int main()
9.{
10. int N, M;
11. cin >> N >> M;
12. vector<int> A(N), B(N - 1);
13. rep(i, 0, N) cin >> A[i];
14. rep(i, 0, N - 1) cin >> B[i];
15.
16. auto calc = [&](int bit) -> int {
17. int res = 0;
18. int now = bit;
19. rep(i, 0, N) {
20. if (now != A[i]) {
21. res++;
22. }
23.
24. if (i < N - 1) {
25. now ^= B[i];
26. }
27. }
28. return res;
29. };
30.
31. cout << min(calc(0), calc(1)) << endl;
32.
33. return 0;
34.}
atcoder.jp favicon

実装時間: 10分

コメント

Twitter では動的計画法っぽく解いている人もいたが、これはE問題意識してるのか?