ganmo::cout

競技プログラミング始めました

AtCoder Regular Contest 114

冷えた

Not coprime (300点)


互いに素でないならばなにかしらの素数がgcdになれば最小になりそう.最小のYを考えるとgcdが同じ素因数を2つ以上持つ必要はないので,50以下の各素数pに対して,各X_ip^2で割りきれるなら割り切れなくなるまでpで割る.割った後,全部のlcmを取って出力とする.制約が小さいので64bit整数型で答えられる.各素数で割り切れるかどうかでbitset使ってorとってもいいかも
拙解 (C++17): Submission #20931367 - AtCoder Regular Contest 114

B - Special Subsets (400点)


関数f(a)は一般に組(a,f(a))の集合として表せることを思い出すと,a \in Sを頂点,(a,f(a)) \in S^2を有向辺として考えられる.その有効グラフはすべての頂点の出次数が1なので,有向森+各弱連結成分につきサイクル1つ(いわゆる「なもりグラフ」)になる.そのサイクルが,条件を満たす部分集合Tの最小単位になる.そのため,サイクルがC個あるとすると答えが2^C-1になる.今回はサイクルの個数と弱連結成分の個数が同じなので,UnionFindで連結成分の個数Cを求めて2^C-1 \bmod 998244353を求めればいい.
拙解 (C++17):
Submission #20940731 - AtCoder Regular Contest 114

C - Sequence Scores (600点)


(ここからコンテスト中に解けなかった)
いわゆる主客転倒.操作の順番が入れ替わってもできる数列は変わらないので,操作は列ではなく集合として扱える.その集合をS(A)と書くと,

\displaystyle
\begin{align}
\mathrm{ans.}
&= \sum_{A} \#S(A)
\end{align}
そこでシグマの順番を入れ替え,操作(l,r,m)に対して,それが含まれる数列A \in [M]^Nの個数を数えればいい.
(以下,解法間違ってたので削除)

D以降

何もわからない