9月1日に開催されたCodeforces Round 970 (Div. 3)に参加した.ABCDEFGの7完で489位.
A - Sakurako’s Exam
問題概要
問題文
a個の1とb個の2からなる長さa+bの数列がある.数列の要素それぞれに対して+または-のいずれかの符号を付けることができるとき(形式的には,それぞれに対して−1倍するかしないかを選べるとき),数列の要素の総和を0にすることができるか?
制約
- 0≤a,b<10
考えたこと
「高速だが考察が必要な解法よりも、計算量は劣るが考察のいらない解法を」の精神で愚直に解いた.
+と-の内訳を全探索する.要素の中に+1がx個(0≤x≤a),+2がy個(0≤y≤b)含まれるとき,数列の総和は
1⋅x+(−1)⋅(a−x)+2⋅y+(−2)⋅(b−y)=2x+4y−a−2b
となるので,(x,y)のそれぞれに対して上の値が0になるか判定すればよい.計算量はO(ab)である.
提出:https://codeforces.com/contest/2008/submission/279078644
B - Square or Not
問題概要
問題文
0または1からなる長さnの文字列sが与えられる.このとき,以下の条件をすべて満たすような正の整数r,cが存在するか判定せよ.
- rc=n
- r=c
- マス(i,j)(1≤i≤r,1≤j≤c)にs(i−1)c+jが書き込まれているようなr×cのグリッドは美しい(beautiful)グリッドである.
ここで,マスに0または1が書き込まれているグリッドが美しいとは,グリッドの周上のマスにすべて1が,そうでないマスにすべて0が書き込まれていることをいう.
制約
- 2≤n≤2×105
- siは
0または1
考えたこと
明らかに,そのようなr,cが存在するためにはnは平方数でなければならない.このときr,cは一意に定まるので,r=c=nとして条件を満たすかどうかを愚直にチェックすればよい.計算量はO(n)になる.
提出:https://codeforces.com/contest/2008/submission/279087603
C - Longest Good Array
問題概要
問題文
整数l,r(l≤r)が与えられる.以下の条件をすべて満たすような長さnの数列(ai)が存在するようなnの最大値を求めよ.
- 数列(ai)は狭義単調増加.すなわち,任意の1≤i<nに対しai<ai+1が成り立つ.
- 数列(ai)の階差は狭義単調増加.すなわち,任意の1<i<nに対しai−ai−1<ai+1−aiが成り立つ.
- 任意の1≤i≤nに対してl≤ai≤r.
制約
- 1≤l≤r≤109
考えたこと
要素がすべてr以下という条件を守りつつ数列の長さをできるだけ大きくしたいので,できるだけ要素の増加を小さく抑えたい.よって
a0a1a2an=l=l+1=l+1+2⋮=l+1+2+⋯+n
とするのが最適で,あとは
l+1+2+⋯+n≤r
すなわち
21n(n+1)≤r−l
であるようなnの最大値を求めればよい.提出コードでは二分探索をした.
提出:https://codeforces.com/contest/2008/submission/279213495
D - Sakurako’s Hobby
問題概要
問題文
1,⋯,nの順列(p1,⋯,pn)が与えられる.整数iが整数j(1≤i,j≤n)に到達可能であるとは,x=iから始めて,整数xをpxに置き換えるという操作を0回以上行うことによってx=jにすることができることをいう.
0または1からなる長さnの文字列sが与えられる.siが0のとき整数piは黒色に,1のとき整数piは白色に塗られていることを示す((pi)は順列なので,この定義により1,⋯,nのすべてに対して色がwell-definedに定まる).
i=1,⋯,nのそれぞれに対して,整数iが到達可能な整数のうち黒色に塗られているものの個数を求めよ.
制約
- 1≤n≤2×105
- 1≤pi≤n
- (p1,⋯,pn)は1,⋯,nの順列
- ∣s∣=n
- siは
0または1
考えたこと
各i=1,⋯,nに対してiからpiに有向辺をはったグラフを考えると,(pi)が順列であることから各連結成分はサイクルになる.よって頂点iからは,iが属する連結成分のすべての頂点に到達可能である.したがって,UnionFindなどを用いて連結成分に含まれる黒色の頂点の個数を数えればよい.
提出:https://codeforces.com/contest/2008/submission/279116356
E - Alternating String
問題概要
問題文
英小文字のみからなる文字列tが交代的(alternating)であるとは,以下の条件がすべて成り立つことをいう.
- ∣t∣は偶数である.
- tの偶数番目の文字がすべて等しい.
- tの奇数番目の文字がすべて等しい.
英小文字のみからなる長さnの文字列sが与えられる.以下の2種類の操作を行なってsを交代的にするために必要な操作回数の最小値を求めよ.
- 操作A:sの中から1文字を選んで削除する.この操作は高々1回だけ行うことができる.
- 操作B:sの中から1文字を選んで,ある英小文字に置き換える.この操作は何回でも行うことができる.
制約
- 1≤n≤2×105
- ∣s∣=n
- siは英小文字
考えたこと
簡単のため0-indexedで考える.
区間[l,r)の偶数番目に文字cがevenc(l,r)回,区間[l,r)の奇数番目に文字cがoddc(l,r)回登場するとする.
nが偶数のとき,偶数番目と奇数番目でそれぞれ登場回数が最多であるような文字に揃えるのが最適である.よって
n−cmaxevenc(0,n)−cmaxoddc(0,n)
が答え.
nが奇数のときは,文字列の長さを偶数にするために,最初に操作Aを適用する必要がある.削除する文字の位置iを固定すると,操作後の文字列において偶数番目に位置するのは,もともとの文字列の区間[0,i)の偶数番目にいた文字と区間[i+1,n)の奇数番目にいた文字である.同様に,操作後の奇数番目はもとの[0,i)の奇数番目と区間[i+1,n)の偶数番目に対応する.よって,i=0,1,⋯,nに対して
n−cmax(evenc(0,i)+oddc(i+1,n))−cmax(oddc(0,i)+evenc(i+1,n))
を求め,その最小値を答えればよい.
evenc(l,r)とoddc(l,r)の値はO(n)かけて累積和を前計算することによりO(1)で取得できるので,計算量はO(n)になる.
提出:https://codeforces.com/contest/2008/submission/279137008
F - Sakurako’s Box
問題概要
問題文
長さnの数列(ai)が与えられる.数列の要素の中から異なる2個の要素を無作為に選ぶとき,選んだ要素の積の期待値を109+7で割った余りを求めよ.
制約
- 2≤n≤2×105
- 0≤ai≤109
考えたこと
直球で典型が来たなあ,という感じの問題.
要するに
n(n−1)2i<j∑aiaj
を求めよ,ということだ.やることは決まっていて,二重シグマの部分を
i<j∑aiaj=i∑aij(>i)∑aj
と変形して内側のシグマの値を累積和から求めればよい.
Codeforcesでは(当然)ac-library-rsが使えないので,用意しておいた自作のmodintを貼った.
提出:https://codeforces.com/contest/2008/submission/279151308
G - Sakurako’s Task
問題概要
問題文
長さnの数列(ai)が与えられる.この数列に対して以下の操作を何回でも行うことができる.
- 操作:ai≥ajなるi,j(i=j)を選び,aiをai−ajまたはai+ajで置き換える.
整数k(≥1)が与えられるので,操作後の数列の要素全体からなる集合Sに対してmexkSの最大値を求めよ.
ここで,非負整数からなる集合Sに対して,x∈/Sなる非負整数x(≥0)のうちk番目に小さいものをmexkSと定義する.
制約
- 1≤n≤2×105
- 1≤k≤109
- 1≤ai≤109
考えたこと
難しかった!
mexkを最大化したいので,数列の値はできるだけ0付近に密集させ,できるだけ互いに異なっているようにしたい.いろいろサンプルを試して,何らかの方法で1を作ることができたら,他の要素から1を複数回引くことで数列の要素を{0,1,⋯,n−1}にすることができ,これがmexkの最大値を与えることに気づいた.もちろん常に1を作るのが可能というわけではないが,結果的にこの考察が解法に至るヒントになった.
n=1のときはそもそも操作ができないので,以降はn>1とする.
このときg=GCD(a1,⋯,an)とおくと,数列の要素はすべてgの倍数である.これは操作後も変わらないから,この操作によってgの倍数以外の数を得ることはできない.一方,ユークリッドの互除法の要領で数列の要素同士を引き算することにより必ずgを作ることができるから,このgを他の要素に対して足し引きすることにより任意のgの倍数を得ることが可能である.よって,mexkを最大化するには,数列の要素を
{0,g,2g,⋯,(n−1)g}
にするように操作を繰り返せばよい.このときのmexkはO(n)かけてシミュレーションをすることにより求まるが,提出コードでは横着して二分探索に頼っている.
提出:https://codeforces.com/contest/2008/submission/279213495