目次
AtCoder Beginner Contest 452 E,F,G問題メモ
E - You WILL Like Sigma Problem
問題文
- あなたの今日のラッキーギリシャ文字はシグマです。シグマを $2$ つも使ったこの問題を解けば、きっと幸運が舞い込むことでしょう。
- 長さ $N$ の正整数列 $A = (A_1, \cdots, A_N)$ および長さ $M$ の正整数列 $B = (B_1, \cdots, B_M)$ が与えられます。
- $\displaystyle \sum_{i=1}^{N} \sum_{j=1}^{M} A_i \cdot B_j \cdot (i \bmod j)$ の値を $998244353$ で割ったあまりを求めてください。
制約
- $1 \leq N,M \leq 5 \times 10^5$
- $1 \leq A_i, B_j \leq 5 \times 10^5$
- 入力される値はすべて整数
解法
唐突に運勢を占われて戸惑う。
$\frac{N}{1}+\frac{N}{2}+\frac{N}{3}+...+\frac{N}{N}$ が $O(N \log{N})$ になるのって、 F~G問題くらいの知識だったイメージがあるけど、Eで出るんですねえ。
ひとまず、$(i,j)$ で表を作って、$(i \bmod j)$ がいくつになるかを表すと、
i\j 1 2 3 4 5 6 7 ... M -------------------------------- 1 0 1 1 1 1 1 1 ... 1 2 0 0 2 2 2 2 2 ... 2 3 0 1 0 3 3 3 3 ... 3 4 0 0 1 0 4 4 4 ... 4 5 0 1 2 1 0 5 5 ... 5 6 0 0 0 2 1 0 6 ... 6
$i=j$ の対角線を境に、右上側は全て $i$ のままとなる。
左下が $j$ 毎に様々な値を取るので厄介だが、これも $j$ 毎に $0,1,2,...,j-1$ を繰り返す周期性はある。
mod をとらない $\displaystyle \sum_{i=1}^{N} \sum_{j=1}^{M} A_i \cdot B_j \cdot i$ ならば、 $\displaystyle \left ( \sum_{i=1}^{N} A_i \cdot i \right ) \cdot \left ( \sum_{j=1}^{M} \cdot B_j \right )$ として、まとめて計算できる。そこからの差分を考えると、
Ai*Bj*i から減らさなければいけない Ai*Bj*x の x i\j 1 2 3 4 5 6 7 8 9 10 ---------------------------------- 1 1 2 2 2 3 3 2 3 4 4 4 3 4 5 5 4 3 4 5 6 6 6 6 4 5 6 7 7 6 6 4 5 6 7 8 8 8 6 8 5 6 7 8 9 9 8 9 8 5 6 7 8 9 10 10 10 9 8 10 6 7 8 9 10
つまり、$j$ 毎に、$j$ の倍数の $i$ で $j$ だけ増えるような構造になっている。累積和を利用すれば、
i\j 1 2 3 4 5 6 ... --------------------------------------- 1 1*B1 │ 2 1*B1 2*B2 │各 j につき、 3 1*B1 3*B3 │i = jk(k=1,2,...)の位置に 4 1*B1 2*B2 4*B4 │j*Bj を加算後、累積和 5 1*B1 5*B5 │ 6 1*B1 2*B2 3*B3 6*B6 │ 7 1*B1 │ 8 1*B1 2*B2 4*B4 │ 9 1*B1 3*B3 │ 10 1*B1 2*B2 5*B5 ↓
各 $i$ につき $A_i \times 累積和[i]$ だけ減じれば、答えとなる。
F - Interval Inversion Count
問題文
- 正整数 $N$ と、$(1,2,\ldots,N)$ の順列 $P=(P _ 1,P _ 2,\ldots,P _ N)$ が与えられます。
- 整数 $K$ が与えられます。次の $2$ つの条件を満たす整数の組 $(l,r)$ がいくつあるか求めてください。
- $1\le l\le r\le N$
- 列 $(P _ l,P _ {l+1},\ldots,P _ r)$ の転倒数が $K$ と等しい。
制約
- $1\le N\le5\times10 ^ 5$
- $0\le K\le\dfrac{N(N-1)}2$
- $1\le P _ i\le N\ (1\le i\le N)$
- $P _ i\ne P _ j\ (1\le i\lt j\le N)$
- 入力はすべて整数
解法
「転倒数が $x$ の区間を内包する区間」の転倒数は必ず $x$ 以上なので、
$[l,r)$ の $l$ を固定して $r$ を伸ばしていき、転倒数が $K+1$ 以上になったら打ち切ってよい。
さらにそこから $l$ を縮めていき、$K$ 以下になったら再び $r$ を伸ばし、、、という尺取法がベースとなる。
Fenwick Tree を使えば、ある数列の末尾に要素追加、または先頭から要素削除して、 転倒数を更新する操作は、$O(\log{N})$ でおこなえる。
転倒数がちょうど $K$ になったところで答えに1ずつ加算していけば良さそうだが、、、
しかし、例えば以下のようなケースでは、
N=7 K=3 1 2 5 4 3 6 7
中央の $(5,4,3)$ の部分で転倒数 $K$ を満たしつつ、 左は $1,2$、右は $6,7$ の任意の箇所まで伸ばしても転倒数は変化しないので、 $9$ 通りの区間が条件を満たすことになる。 こういうのが、単純な尺取法では上手く処理できない。
尺取法で $r$ に相当するポインタを2つ持ち、
- $r_1$: 転倒数がはじめて $K$ 以上となる位置
- $r_2$: 転倒数がはじめて $K+1$ 以上となる位置
とすれば、各 $l$ を固定した場合につき、$r_2-r_1$ が答えとなる。
ただし、$K=0$ の時は $r_1$ が上手く働かないので、別に求める。
G - 221 Substring
問題文
- 正整数からなる数列 $X = (X_1, \dots, X_n)$ に対し、その連長圧縮の任意の (長さ・値) ペアにおいて長さと値が等しいとき、かつそのときに限り、$X$ を 221 数列 と呼びます。
- たとえば、$(2,2,3,3,3,1,2,2)$ は 221 数列ですが、$(1,1)$ や $(4,4,1,4,4)$ は 221 数列ではありません。
- 長さ $N$ の正整数列 $A = (A_1, \dots, A_N)$ が与えられます。$A$ の空でない連続部分列として現れる 221 数列としてあり得るものの個数を求めてください。
- ただし、異なる位置から取り出した連続部分列であっても、数列として一致するものは区別せずまとめて $1$ 通りとして数えます。
制約
- $1 \leq N \leq 500\,000$
- $1 \leq A_i \leq 9$
- 入力される値はすべて整数
解法
「221文字列の種類数」の問題を、単なる「部分文字列の種類数」に言い換えるのはそこまで難しくない。
$A$ を連長圧縮して、(長さ $l$、値 $c$) の各ペアに付き、
5 5 5のように、$l \lt c$ のとき、221文字列に含めることはできない。3 3 3のように、$l = c$ のとき、221文字列のどこに出現しても良い要素となる。2 2 2のように、$l \gt c$ のとき、221文字列の端にのみ出現できる要素となる。
よって、連長圧縮の $(l,c)$ を、$c$ に置換しつつ、$l \neq c$ の箇所で数列を区切っていく。
5 5 5 3 3 3 2 2 2 1 1 1 4 4 4 4 1 2 2 8 2 2 2 2 3 3 3
↓
| 3 2 | 2 1 | 1 4 1 2 | 2 | 2 3
→ (3,2), (2,1), (1,4,1,2), (2), (2,3)
これらの複数の数列の中に登場する、ユニークな部分文字列の種類数を数えたい。
これはやや高度な典型問題で、Suffix Automaton が使える。
または、公式Editorialのように、1~9以外の文字(たとえば0)で全て連結した上で Suffix Array + LCP からも求めることができる。

