2024-09-02

Codeforces Round 970 (Div. 3)に参加した

競プロアルゴCodeforces

Codeforces Div. 3の参加記.

9月1日に開催されたCodeforces Round 970 (Div. 3)に参加した.ABCDEFGの7完で489位.

A - Sakurako’s Exam

問題概要

問題文

aa個の11bb個の22からなる長さa+ba+bの数列がある.数列の要素それぞれに対して+または-のいずれかの符号を付けることができるとき(形式的には,それぞれに対して1-1倍するかしないかを選べるとき),数列の要素の総和を00にすることができるか?

制約

考えたこと

「高速だが考察が必要な解法よりも、計算量は劣るが考察のいらない解法を」の精神で愚直に解いた.

+-の内訳を全探索する.要素の中に+1+1xx(0xa)(0\leq x\leq a)+2+2yy(0yb)(0\leq y\leq b)含まれるとき,数列の総和は

1x+(1)(ax)+2y+(2)(by)=2x+4ya2b1\cdot x+(-1)\cdot (a-x)+2\cdot y+(-2)\cdot (b-y)=2x+4y-a-2b

となるので,(x,y)(x, y)のそれぞれに対して上の値が00になるか判定すればよい.計算量はO(ab)O(ab)である.

提出:https://codeforces.com/contest/2008/submission/279078644

B - Square or Not

問題概要

問題文

0または1からなる長さnnの文字列ssが与えられる.このとき,以下の条件をすべて満たすような正の整数r,cr, cが存在するか判定せよ.

ここで,マスに0または1が書き込まれているグリッドが美しいとは,グリッドの周上のマスにすべて1が,そうでないマスにすべて0が書き込まれていることをいう.

制約

考えたこと

明らかに,そのようなr,cr,cが存在するためにはnnは平方数でなければならない.このときr,cr,cは一意に定まるので,r=c=nr=c=\sqrt{n}として条件を満たすかどうかを愚直にチェックすればよい.計算量はO(n)O(n)になる.

提出:https://codeforces.com/contest/2008/submission/279087603

C - Longest Good Array

問題概要

問題文

整数l,r  (lr)l, r\;(l\leq r)が与えられる.以下の条件をすべて満たすような長さnnの数列(ai)(a_i)が存在するようなnnの最大値を求めよ.

制約

考えたこと

要素がすべてrr以下という条件を守りつつ数列の長さをできるだけ大きくしたいので,できるだけ要素の増加を小さく抑えたい.よって

a0=la1=l+1a2=l+1+2an=l+1+2++n\begin{align*} a_0&=l\\ a_1&=l+1\\ a_2&=l+1+2\\ &\vdots\\ a_n&=l+1+2+\cdots +n \end{align*}

とするのが最適で,あとは

l+1+2++nrl+1+2+\cdots +n\leq r

すなわち

12n(n+1)rl\frac{1}{2}n(n+1)\leq r-l

であるようなnnの最大値を求めればよい.提出コードでは二分探索をした.

提出:https://codeforces.com/contest/2008/submission/279213495

D - Sakurako’s Hobby

問題概要

問題文

1,,n1,\cdots, nの順列(p1,,pn)(p_1,\cdots, p_n)が与えられる.整数iiが整数j  (1i,jn)j\; (1\leq i,j\leq n)到達可能であるとは,x=ix=iから始めて,整数xxpxp_xに置き換えるという操作を00回以上行うことによってx=jx=jにすることができることをいう.

0または1からなる長さnnの文字列ssが与えられる.sis_i0のとき整数pip_iは黒色に,1のとき整数pip_iは白色に塗られていることを示す((pi)(p_i)は順列なので,この定義により1,,n1,\cdots, nのすべてに対して色がwell-definedに定まる).

i=1,,ni=1,\cdots, nのそれぞれに対して,整数iiが到達可能な整数のうち黒色に塗られているものの個数を求めよ.

制約

考えたこと

i=1,,ni=1,\cdots, nに対してiiからpip_iに有向辺をはったグラフを考えると,(pi)(p_i)が順列であることから各連結成分はサイクルになる.よって頂点iiからは,iiが属する連結成分のすべての頂点に到達可能である.したがって,UnionFindなどを用いて連結成分に含まれる黒色の頂点の個数を数えればよい.

提出:https://codeforces.com/contest/2008/submission/279116356

E - Alternating String

問題概要

問題文

英小文字のみからなる文字列tt交代的(alternating)であるとは,以下の条件がすべて成り立つことをいう.

英小文字のみからなる長さnnの文字列ssが与えられる.以下の22種類の操作を行なってssを交代的にするために必要な操作回数の最小値を求めよ.

制約

考えたこと

簡単のため0-indexedで考える.

区間[l,r)[l, r)の偶数番目に文字ccevenc(l,r){\rm even}_c(l,r)回,区間[l,r)[l, r)の奇数番目に文字ccoddc(l,r){\rm odd}_c(l,r)回登場するとする.

nnが偶数のとき,偶数番目と奇数番目でそれぞれ登場回数が最多であるような文字に揃えるのが最適である.よって

nmaxcevenc(0,n)maxcoddc(0,n)n-\max_c {\rm even}_c(0, n)-\max_c {\rm odd}_c(0, n)

が答え.

nnが奇数のときは,文字列の長さを偶数にするために,最初に操作Aを適用する必要がある.削除する文字の位置iiを固定すると,操作後の文字列において偶数番目に位置するのは,もともとの文字列の区間[0,i)[0, i)の偶数番目にいた文字と区間[i+1,n)[i+1, n)の奇数番目にいた文字である.同様に,操作後の奇数番目はもとの[0,i)[0, i)の奇数番目と区間[i+1,n)[i+1, n)の偶数番目に対応する.よって,i=0,1,,ni=0,1,\cdots, nに対して

nmaxc(evenc(0,i)+oddc(i+1,n))maxc(oddc(0,i)+evenc(i+1,n))n-\max_c ({\rm even}_c(0, i)+{\rm odd}_c(i+1, n))-\max_c ({\rm odd}_c(0, i)+{\rm even}_c(i+1, n))

を求め,その最小値を答えればよい.

evenc(l,r){\rm even}_c(l,r)oddc(l,r){\rm odd}_c(l,r)の値はO(n)O(n)かけて累積和を前計算することによりO(1)O(1)で取得できるので,計算量はO(n)O(n)になる.

提出:https://codeforces.com/contest/2008/submission/279137008

F - Sakurako’s Box

問題概要

問題文

長さnnの数列(ai)(a_i)が与えられる.数列の要素の中から異なる2個の要素を無作為に選ぶとき,選んだ要素の積の期待値を109+710^9+7で割った余りを求めよ.

制約

考えたこと

直球で典型が来たなあ,という感じの問題.

要するに

2n(n1)i<jaiaj\frac{2}{n(n-1)}\sum_{i < j}a_ia_j

を求めよ,ということだ.やることは決まっていて,二重シグマの部分を

i<jaiaj=iaij(>i)aj\sum_{i < j}a_ia_j=\sum_i a_i\sum_{j(>i)}a_j

と変形して内側のシグマの値を累積和から求めればよい.

Codeforcesでは(当然)ac-library-rsが使えないので,用意しておいた自作のmodintを貼った.

提出:https://codeforces.com/contest/2008/submission/279151308

G - Sakurako’s Task

問題概要

問題文

長さnnの数列(ai)(a_i)が与えられる.この数列に対して以下の操作を何回でも行うことができる.

整数k  (1)k\;(\geq 1)が与えられるので,操作後の数列の要素全体からなる集合SSに対してmexkS{\rm mex}_k Sの最大値を求めよ.

ここで,非負整数からなる集合SSに対して,xSx\notin Sなる非負整数x  (0)x\;(\geq 0)のうちkk番目に小さいものをmexkS{\rm mex}_k Sと定義する.

制約

考えたこと

難しかった!

mexk{\rm mex}_kを最大化したいので,数列の値はできるだけ00付近に密集させ,できるだけ互いに異なっているようにしたい.いろいろサンプルを試して,何らかの方法で11を作ることができたら,他の要素から11を複数回引くことで数列の要素を{0,1,,n1}\{0,1,\cdots, n-1\}にすることができ,これがmexk{\rm mex}_kの最大値を与えることに気づいた.もちろん常に11を作るのが可能というわけではないが,結果的にこの考察が解法に至るヒントになった.

n=1n=1のときはそもそも操作ができないので,以降はn>1n>1とする.

このときg=GCD(a1,,an)g={\rm GCD}(a_1,\cdots, a_n)とおくと,数列の要素はすべてggの倍数である.これは操作後も変わらないから,この操作によってggの倍数以外の数を得ることはできない.一方,ユークリッドの互除法の要領で数列の要素同士を引き算することにより必ずggを作ることができるから,このggを他の要素に対して足し引きすることにより任意のggの倍数を得ることが可能である.よって,mexk{\rm mex}_kを最大化するには,数列の要素を

{0,g,2g,,(n1)g}\{0, g, 2g,\cdots, (n-1)g\}

にするように操作を繰り返せばよい.このときのmexk{\rm mex}_kO(n)O(n)かけてシミュレーションをすることにより求まるが,提出コードでは横着して二分探索に頼っている.

提出:https://codeforces.com/contest/2008/submission/279213495