目次

AtCoder Beginner Contest 230 F,G問題メモ

AtCoder Beginner Contest 230

平日コン、のーみそが疲れてると問題文の内容が頭に入ってこない。

F - Predilection

F - Predilection

問題

解法

累積和で考える。

$A$ の累積和を $B$ 、最終的な数列の一例を $C$ 、その累積和を $D$ とする。

すると $D$ は、$B$ からいくつかを(順番を変えずに)かいつまんだ部分列と見ることができる。
(ただし最後の $B_N$ は必ず使う)

A   1  0  2  1 -3  2  1  0
B   1  1  3  4  1  3  4  4

    |-->  >  |----------->
C      1  2              1
D      1  3              4

$C$ と $D$ は1対1対応するので、$D$ の個数を数えればよい。

列として同じになってしまうものが存在するので、それを重複して数えてはいけない。

i   1  2  3  4  5  6  7  8
--------------------------
A   1  0  2  1 -3  2  1  0
B   1  1  3  4  1  3  4  4
    >  |----------->  |-->
C   1              2     1    上の例とC,Dが同じ
D   1              3     4

DPで考える。

遷移は、基本的には $DP[1]~DP[i-1]$ のそれぞれから遷移できて以下のようになる。

ただし、複数含まれる要素は最後の1要素からしか遷移できない

i   1  2  3  4  5  6  7  8
--------------------------
B   1  1  3  4  1  3  4  4
                      *       DP[7] へ遷移できるのは
             *  *  *          この3つだけ

i=3 と i=6 は Bi が 3 で同じ。
DP[3] に数えられている具体的な部分列は (1 3) (1 1 3) などがあるが、
これらは必ず全て、DP[6]にも数えられている。

これは、$i=1,2,...$ と $DP$ を求めていく過程で、「要素 $a$ が最後に出現した $i$」を辞書型などで更新していくとよい。

$O(N)$ で最後まで求められる。

Python3

G - GCD Permutation

G - GCD Permutation

問題

解法

基本的に公式Editorialの踏襲。

GCD条件が1つの場合

仮に、$GCD(P_i,P_j) \neq 1$ を無視して $GCD(i,j) \neq 1$ だけに絞って考えると、

と、互いに何らかの数の倍数だったら当てはまる。

たとえば2の倍数は $\dfrac{N}{2}$ 個(切り捨て)あるので、 これを $s$ とおくと $\dfrac{s(s+1)}{2}$ 個のペアが存在する。
(この問題では自分自身とのペアも許される点に注意)

$a=2~N$ について、$a$ の倍数の中で作れるペアの個数 $Pair(a)=\dfrac{\frac{N}{a}(\frac{N}{a}+1)}{2}$ を合計すると答え……にはならない。

重複が発生するので、上手く除かないといけない。
たとえば6と12は、$2,3,6$ の3回で数えられてしまう。

メビウス関数

そういうときに便利に使えるのがメビウス関数(を改変したもの)となる。
包除原理の約数特化版みたいな感じ。

\[ \tilde{\mu}(n)= \begin{cases} 1 & (nが相異なる奇数個の素数の積で表されるとき (n=2,3,30 など) ) \\ -1 & (nが相異なる偶数個 (0 を含まない) の素数の積で表されるとき (n=6,10,210 など) ) \\ 0 & (それ以外のとき (n=1,4,8,9,12 など) ) \end{cases} \]

2以上のどんな整数についても、約数の $\tilde{\mu}(x)$ を足し合わせると、必ず $1$ になるという性質を持つ。

なので、6と12の場合も、

とすると、きちんと重複をのぞける。

よって、$1~N$ で互いに素でない組の個数は、$\displaystyle \sum_{a=2}^{N}\tilde{\mu}(a)Pair(a)$ となる。

二重化

さて、これでGCD条件が1つの場合は答えを求められた。
しかし今回はGCD条件が2つある。

$a=2~N$ について、添字が互いに $a$ の倍数である $P_a,P_{2a},P_{3a},...$ の中に限定して、 再び $b=2~N$ について「2の倍数の個数」……「$N$ の倍数の個数」を調べていけば答えは求まる。

$g(a,b)$ を「添字が $a$ の倍数である $P_i$ に限定した中での $b$ の倍数の個数」とすると、 $\displaystyle \sum_a \sum_b \tilde{\mu}(a)\tilde{\mu}(b)\dfrac{g(a,b)(g(a,b)+1)}{2}$ が答えとなる。

添字ならば規則的に並んでいるため「$a$ の倍数の個数」は割り算で求められたが、 抽出された中では「$b$ の倍数の個数」は実際に全部試すしかない。 そのためこれを愚直に行うと、計算量は全体で $O(N^2)$ となってしまう。

しかし、個数が限定されている場合、メビウス関数の性質も併せて考えると、実は調べるべき $b$ はそれほど多くない。

$b$ の方を1つ1つ試すのではなく、各 $P_a,P_{2a},...$ について、それらが持つ約数の方からアプローチする。

つまり、「$count[b]=b$ を約数に持つ、限定された中での $P_i$ の個数」とした記録用辞書を作っておき、
たとえば $P_i$ が $2,3,6$ を約数に持つのであれば、$count[2],count[3],count[6]$ にそれぞれ+1する。

$P_a,P_{2a},...$ についてこれを行えば、$count$ から各値を約数に持つ $P_i$ が何個あるかがわかる。

だがそれでも、約数は $N \le 2 \times 10^5$ の中では最大 $160$ 個とかになり、言語によってはやや厳しい。

さらに絞ると、同じ素因数を2個以上含む約数は $\tilde{\mu}(x)$ が $0$ になる(答えへの寄与も0)ので、 約数のうちそれらは無視できる。
$P_i$ が $2^p3^q5^r$ という風に素因数分解できるなら、 $count$ に記録すべき約数は、$2,3,5$ をそれぞれ含むか含まないか、から $1$ を除いた $2^3-1=7$ 通りだけでよい。

これなら、$P_i \le 2 \times 10^5$ の範囲で素因数の種類数はたかだか $6$ 個(考慮すべき約数は $2^6-1=63$ 個)、 しかもそんな特異な数は限られていて多くはせいぜい $1~3$ 個くらいなので、間に合う。

まとめ

あらかじめ、$1~N$ について「$\tilde{\mu}(x)$」および「約数のうち $\tilde{\mu}(x)$ が0でないもののリスト」を計算しておく。

$a=2~N$ について、以下の要領で $P_a,P_{2a},...$ を調べていく。

$1~N$ の素因数の種類数の最大値を $d(N)$ として、$O(2^{d(N)} N \log{N})$(実際はもっと少ない)で求められる。

Python3