AtCoder Beginner Contest 436 E,F,G問題メモ

AtCoder Beginner Contest 436

ライブラリ準備不足!

E - Minimum Swap

問題文

  • $(1,2,\ldots,N)$ を並べ替えた整数列 $P=(P _ 1,P _ 2,\ldots,P _ N)$ が与えられます。
  • あなたは、次の操作を $0$ 回以上行って $P$ を列 $(1,2,\ldots,N)$ と一致させたいです。
    • $1\le i\lt j\le N$ を満たす整数の組 $(i,j)$ をひとつ選ぶ。$P _ i$ と $P _ j$ の値を入れ替える。
  • $P$ を列 $(1,2,\ldots,N)$ と一致させるために必要な最小の操作回数を $K$ 回とします。
  • $K$ 回の操作で $P$ を列 $(1,2,\ldots,N)$ と一致させるような操作列の $\mathbf{1}$ 回目の操作としてあり得る操作の数を求めてください。
  • ただし、$2$ つの操作は選んだ整数の組 $(i,j)$ が異なるとき、またそのときに限り区別します。

制約

  • $2\le N\le3\times10 ^ 5$
  • $1\le P _ i\le N\ (1\le i\le N)$
  • $P _ i\ne P _ j\ (1\le i\lt j\le N)$
  • $i\ne P _ i$ を満たす $1\le i\le N$ が存在する
  • 入力はすべて整数

解法

順列上で任意swapを繰り返してソートする問題。ここ数年のABCでは頻出のテーマ。

頂点 $1~N$ を用意し、$i→P_i$ に辺を張ったグラフを考えると、いくつかのサイクルができる。

同じサイクル上の任意の2点 $(i,j)$ を $P$ で入れ替えると、対応するグラフではサイクルが必ず1個増える。
最終的にサイクルが $N$ 個になったら完成。

よって、サイクル毎に独立に考えられる。
$c$ 頂点のサイクルからは、$\frac{c(c-1)}{2}$ 通りの $(i,j)$ の選び方がある。
サイクル毎にサイズ $c$ を調べて、上の計算結果を合計したら答え。

Python3

F - Starry Landscape Photo

問題文

  • AtCoder 星から見える夜空には $N$ 個の星があり、これらの $N$ 個の星は東から西へ一直線上に並んでいます。
  • 東から $i$ 番目 $(1\le i\le N)$ の星は、これらの星の中で $B _ i$ 番目に明るい星です。
  • 高橋くんは、次のような手順で夜空の写真を撮ることにしました。
    • $1\le l\le r\le N$ を満たす整数の組 $(l,r)$ を選び、東から $l$ 番目、$l+1$ 番目、$\ldots$、$r$ 番目の星が全てフレームに収まり、他の星がフレームに入らないようにカメラを設置する。
    • $1\le b\le N$ を満たす整数 $b$ を選び、$N$ 個の星のうち明るさが $1$ 番目から $b$ 番目に入る(かつフレームに収まっている)星がすべて写り、そうでない星が写らないようにシャッターを開放する。
  • ただし、星が $1$ つも写らないように写真を撮ることはできません。
  • このようにして撮影された夜空の写真に写っている星の集合としてありえるものが何通りあるか求めてください。

制約

  • $1\le N\le5\times10 ^ 5$
  • $1\le B _ i\le N\ (1\le i\le N)$
  • $B _ i\ne B _ j\ (1\le i\lt j\le N)$
  • 入力はすべて整数

解法

カメラに「光量を絞る」機能があり、 「フレームに入っていても映らない星があるように自由に明るさを調節できる」ことを理解していないと、 問題文の意図が若干伝わりづらいか。 (最近のデジカメは気にしなくても最適な明るさにしてくれ、意識して光量を調節することが稀なので)
まぁ、サンプルを見ればすぐ分かるようにしてくれている。

カメラに写っている最も暗い星で場合分けする。

この時、写真に写っている (最も左の星、最も右の星) の組の個数だけ、異なる星の集合ができる。

  • $L_i:=$ 星 $i$ より左で、$B_i$ より明るい星の個数
  • $R_i:=$ 星 $i$ より右で、$B_i$ より明るい星の個数

とすると、最も暗い星を $i$ としたときの答えへの寄与は

  • $(L_i+1)\times(R_i+1)$

で求められる。

転倒数を求める時のように FenwickTree などを使えば、$L_i,R_i$ を $O(N \log{N})$ で計算できる。

Python3

G - Linear Inequation

問題文

  • 長さ $N$ の正整数列 $A=(A _ 1,A _ 2,\ldots,A _ N)$ および正整数 $M$ が与えられます。
  • 次の条件を満たす長さ $N$ の非負整数列 $x=(x _ 1,x _ 2,\ldots,x _ N)$ がいくつあるか求めてください。
    • $\displaystyle\sum _ {i=1} ^ NA _ ix _ i\le M$
  • 答えは非常に大きくなる場合があるので、答えを $998244353$ で割った余りを求めてください。

制約

  • $1\le N\le100$
  • $1\le A _ i\le100\ (1\le i\le N)$
  • $1\le M\le10 ^ {18}$
  • 入力はすべて整数

解法

最近、FPS 24 題 という、形式的冪級数をテーマとしたコンテストがあった。
これのおかげで、解法を連想しやすかった人が増えたかもしれない。

問題文中の $x$ と被るのでややこしいが、今後、$x$ は形式的冪級数に用いる変数を指すとする。

形式的冪級数に置き換えて考えると、

  • $F_1(x)=1+x^{A_1}+x^{2A_1}+x^{3A_1}+...$
  • $F_2(x)=1+x^{A_2}+x^{2A_2}+x^{3A_2}+...$
  • $F_N(x)=1+x^{A_N}+x^{2A_N}+x^{3A_N}+...$

という多項式 $N$ 個の積 $F_1F_2...F_N(x)$ の、$x^0~x^M$ の係数の合計が答えとなる。

このような指数が等間隔に無限に続く式は、$F_i(x)=\dfrac{1}{1-x^{A_i}}$ というようにも表すことができる。
また、数列の初項からの累積和は、形式的冪級数としては $\dfrac{1}{1-x}$ をかけることに相当する。
よって求めたい多項式は

  • $G(x)=\dfrac{1}{(1-x)(1-x^{A_1})(1-x^{A_2})...(1-x^{A_N})}$

のように表せる。

$G(x)$ の分母の次数は制約より、高々 $O(N \max(A)) \simeq 10^4$ である。
1つずつ畳み込みでマージしていけば、$O(N^2 \max(A) \log{(N \max(A))})$ で、全て展開した形を求められる。

$G(x)$ の $x^M$ の項の係数を求めたい。

母関数が分かっている数列の $M$ 項目を高速に求める方法として、Bostan-Mori がある。
母関数の次数を $d$ として、$O(d \log{d} \log{M})$ で求められる。

Python3

programming_algorithm/contest_history/atcoder/2025/1213_abc436.txt · 最終更新: by ikatakos
CC Attribution 4.0 International
Driven by DokuWiki Recent changes RSS feed Valid CSS Valid XHTML 1.0