WCPC
AtCoder

ABC457参加記

2025年5月9日 S ShoboiNamae

前回の参加記(ABC456回)

はじめに

こんにちは。
初めまして!ShoboiNamaeと申します。今回、入緑を記念して記事を書かせていただけることになりました!(やったね!)
新入部員として、当たり障りのないことを書いていければと思います。

結果サマリ

問題参加者名タイム言語
Ansubaru0:25Java
Bnsubaru1:53Java
CShoboiNamae9:12C++
DShoboiNamae39:25C++
Ensubaru97:45Java
F---
G---

今週の出題

ABC457-A

問題文を表示

問題文
長さ NN の数列 A=(A1,A2,...,AN)A = (A_1, A_2, ... , A_N) が与えられます。
その後に 11 以上 NN 以下の整数 XX が与えられます。
AXA_X の値を出力してください。

制約

  • 1XN1001 \le X \le N \le 100
  • 1Ai1001 \le A_i \le 100
  • 入力される値はすべて整数

入力
NN
A1    A2    ...    ANA_1 \;\; A_2 \;\; ... \;\; A_N
XX

出力
AXA_X の値を出力せよ。

A問題は1次元の配列に入力して、添え字が0から始まることに注意して出力することで解けました。

配列を使わないこともできます!(時間の無駄)

配列を使わないコードはこちら(C++)

ABC457-B

問題文を表示

問題文
NN 個の数列 A1,A2,...,ANA_1, A_2,..., A_N が与えられます。
数列 AiA_i の長さは LiL_i であり Ai=(Ai,1,Ai,2,...,Ai,Li)A_i = ( A_{i, 1}, A_{i, 2},..., A_{i, L_i} )です。
その後、整数 X,YX, Y が与えられます。 AX,YA_{X, Y} の値を出力してください。

制約
1N2×1051 \le N \le 2 \times 10^5
1Li1 \le L_i
LiL_i の総和は 2×1052 \times 10^5 以下
1Ai,j10001 \le A_{i, j} \le 1000
1XN1 \le X \le N
1YLX1 \le Y \le L_X
入力される値はすべて整数

入力
NN
L1    A1,1    A1,2    ...    A1,L1L_1 \;\; A_{1, 1} \;\; A_{1, 2} \;\; ... \;\; A_{1, L_1}
L2    A2,1    A2,2    ...    A2,L2L_2 \;\; A_{2, 1} \;\; A_{2, 2} \;\; ... \;\; A_{2, L_2}

LN    AN,1    AN,2    ...    AN,LNL_N \;\; A_{N, 1} \;\; A_{N, 2} \;\; ... \;\; A_{N, L_N}
X    YX \;\; Y

出力
AX,YA_{X, Y} の値を出力せよ。

Aと同様に配列の操作が本質の問題ですが、こちらは2次元配列を使う問題でした。
数列 AiA_i の長さがそれぞれ違うので入力が複雑になるところが難しかったと思います。

解説を読んでみると、固定長配列を作ろうとした人がWAになるような問題設定にされていたようです。よく考えられてるなあ。

ABC457-C

問題文を表示

問題文
整数 N,KN, KNN 個の整数列 A1,A2,...,ANA_1, A_2,..., A_N 、 長さ NN の整数列 C=(C1,C2,...,CN)C = (C_1, C_2,..., C_N) が与えられます。整数列 AiA_i の長さは LiL_i であり Ai=(Ai,1,Ai,2,...,Ai,Li)A_i = (A_{i, 1}, A_{i, 2},..., A_{i, L_i}) です。また、 1Ki=1N(CiLi)1 \le K \le \sum_{i=1}^N (C_iL_i) が保証されます。
AACC から以下の手順で整数列 B=(B1,B2,...,Bi=1N(CiLi))B = (B_1, B_2,..., B_{\sum_{i=1}^N (C_iL_i)}) を構成します。

  • BB を長さ0の整数列とする。
  • i=1,2,...,Ni = 1, 2,..., N の順に以下の操作を行う:
    • BB の末尾に AiA_i を連結させる操作を CiC_i 回行う。

BKB_K の値を求めてください。

制約

  • 1N1 \le N
  • 1Li1 \le L_i
  • i=1NLi2×105\sum_{i=1}^N L_i \le 2 \times 10^5
  • 1A{i,j}109    (1jLi)1 \le A_\{i, j\} \le 10^9 \;\; (1 \le j \le L_i)
  • 1Ci1091 \le C_i \le 10^9
  • 1Ki=1N(CiLi)1 \le K \le \sum_{i=1}^N (C_iL_i)
  • 入力される値はすべて整数

入力
N    KN \;\; K
L1    A1,1    A1,2    ...    A1,LiL_1 \;\; A_{1, 1} \;\; A_{1, 2} \;\; ... \;\; A_{1, L_i}
L2    A2,1    A2,2    ...    A2,L2L_2 \;\; A_{2, 1} \;\; A_{2, 2} \;\; ... \;\; A_{2, L_2}

LN    AN,1    AN,2    ...    AN,LNL_N \;\; A_{N, 1} \;\; A_{N, 2} \;\; ... \;\; A_{N, L_N}
C1    C2    ...    CNC_1 \;\; C_2 \;\; ... \;\; C_N

出力
答えを出力せよ。

解説文を表示(長くなったのでたたみました) この問題は入力や数列のある要素の値を求める点でB問題に似ていますがだいぶ難易度が違います。
愚直に数列BBを作ると間に合わないorメモリ超過するので数列Bを作らずに解く工夫が必要でした。

まず、 「 BB の末尾に AiA_i を連結させる操作を CiC_i 回行う」という点に着目します。すると、数列 BB の中に 「 AiA_i が繰り返されている部分」が、 i=1i = 1 から i=Ni = N までの NN 箇所あることが分かります。
このとき、 数列 BB の「 AiA_i が繰り返されている部分」を、数列 BB の第 ii 群と定義します。数列 BB の第 KK 項が属する群と、その群における位置を求めます。
問題文から、第 ii 群の長さは CiLiC_iL_i です。よって、第1群から第jj群の最後の要素までの項数は、 (C1L1+C2L2+...+CjLj)=i=1j(CiLi)(C_1L_1 + C_2L_2 + ... + C_jL_j) = \sum_{i=1}^j (C_iL_i) 項です。
このことから、数列 BB の第 KK 項が属する群を第 mm 群とすると、i=1m1(CiLi)<Ki=1m(CiLi)\sum_{i=1}^{m-1} (C_iL_i) \lt K \le \sum_{i=1}^m (C_iL_i) が成り立ちます。for文などで、 Ki=1m(CiLi)K \le \sum_{i=1}^m (C_iL_i) が満たされる間 mm を1から増やしていくことで mm を求めることができます。
mm が分かってしまえば群の中の第何項目なのかは、 Ki=1m1(CiLi)K - \sum_{i=1}^{m-1} (C_iL_i) で簡単に求まります。
肝心の出力すべき要素についても、第 mm 群で長さ LmL_m の数列 AmA_m が繰り返されていることを考えると、Ki=1m1(CiLi)K - \sum_{i=1}^{m-1} (C_iL_i)LmL_m で割ったあまりを考えればよさそうです。
ただし、大抵のプログラミング言語の配列は 0-indexed (添え字が0始まり)なので、添え字を指定するときには注意が必要です。

と、なぜか無駄に解説を書いてしまったのですが、本番中はこんなに考えてません。
私は読解力がとても低いので問題文を読むのに一番苦労しました。あと、最後の添え字もなんとなくでやってしまった。通ったからいいけれども。

あと、全然関係ないんですが、0-indexedって競プロ界隈限定の呼び方なんですかね? 検索しても競プロのサイトばかりヒットするのはなぜだろう…

まとめると、この問題は難しかったということです。

ABC457-D

問題文を表示

問題文
長さ NN の数列 A=(A1,A2,...,AN)A = (A_1, A_2,..., A_N) と整数 KK が与えられます。
あなたは次の操作を0回以上 KK 回以下行うことができます。

  • 1iN1 \le i \le N を満たす整数 ii を1つ選び、 AiA_iii を加える。

操作後の数列に対する min1iNAi\underset{1 \le i \le N}{\min} A_i としてありうる最大値を求めてください。

制約

  • 1N2×1051 \le N \le 2 \times 10^5
  • 1Ai10181 \le A_i \le 10^{18}
  • 1K10181 \le K \le 10^{18}
  • 入力される値はすべて整数

入力
N    KN \;\; K
A1    A2    ...    ANA_1 \;\; A_2 \;\; ... \;\; A_N

出力
答えを出力せよ。

またまた数列が出てきました。今日は数列デーなのか?
私は先週のABCでD問題が解けなかったので何としても解きたいところでした。
まだまだ経験が浅く、コンテスト中は「DはDPのD!」とか言ってDPを考えていましたが、途中で天啓があり、にぶたんだと確信したので爆速でコードを書き、しっかりオーバーフローでWAになって踊りました。
その後、考えるのを放棄し、 __int128_t 型を使うという脳筋プレーでACできました。なので、今回一番面倒だったのは __int128_t の出力関数を作ることでした。
といっても、10で割ってあまり出力して10で割って…を繰り返すだけの関数ですが。

Pythonはいいよなあ。デフォルトが多倍長整数で。

後から聞いた話ですが、最小値の最大化とか、最大値の最小化とか、そういう類の問題は大体にぶたんらしいです。もしにぶたんできなかったら、その後にDPとか貪欲を考えるのがいいそうです。
やっぱり O(log N) は魅力的だー。

ABC457-E

問題文を表示

問題文
NN 個のマスが左右一列に並んでいます。左から ii 番目 (1iN)(1 \le i \le N) のマスをマス ii と呼びます。

MM 枚の布があり、布 i    (1iM)i \;\; (1 \le i \le M) を敷くとマス LiL_i からマス RiR_i までを覆うことができます。

QQ 個のクエリに答えてください。 qq 番目 (1qQ)(1 \le q \le Q) のクエリでは整数 Sq,TqS_q, T_q が与えられるので、以下の問題に答えてください。

  • MM 枚の布の中からちょうど2枚の布を選んで敷くことで、以下の条件を満たすことができるか判定せよ。
    • マス SqS_q からマス TqT_q までは1枚以上の布で覆われており、それ以外のマスは布で覆われていない。

制約

  • 1N2×1051 \le N \le 2 \times 10^5
  • 2M2×1052 \le M \le 2 \times 10^5
  • 1LiRiN1 \le L_i \le R_i \le N
  • 1Q<2×1051 \le Q \lt 2 \times 10^5
  • 1SqTqN1 \le S_q \le T_q \le N
  • 入力される値はすべて整数

入力
N    MN \;\; M
L1    R1L_1 \;\; R_1
L2    R2L_2 \;\; R_2

LM    RML_M \;\; R_M
QQ
S1    T1S_1 \;\; T_1
S2    T2S_2 \;\; T_2

SQ    TQS_Q \;\; T_Q

出力
各クエリに対する答えを改行区切りで出力せよ。
各クエリでは、条件を満たすように2枚の布を選ぶことができる場合は Yes を、できない場合は No を出力せよ。

私はコンテスト中に解けませんでした。ランキングを見てみると、 nsubaru 先輩が解いてる!! さすがすぎる!!
一応私がコンテスト中に考えたことを書いておきます。

実行時間が2.5秒と、少し長かったので重めの計算量を通すと推測し、前処理ですべての覆える範囲を探索するコードを提出しましたがもちろんTLEでした。さすがに O(M^2) は通らない。
全探索じゃないっぽいなー、また二分探索? 今日二分探索デーか? というところまでは考えましたが、どうすればいいのか分からなかったので成す術なく終わりました。

ABC457-F以降

(これ以降の問題は割愛します)

最後に

E問題を解けなかったことが悔しいですが、なんとか入緑できてよかったです。

至らない点もあったかと思いますが、最後まで読んでいただきありがとうございました。

← 活動記事一覧に戻る