AtCoder Beginner Contest 428(Promotion of AtCoderJobs)D,E,F,G問題メモ

D - 183184

問題文

  • 正整数 $x,y$ に対して $f(x,y)$ を以下で定義します。
    • 十進表記の $x,y$ をそれぞれ文字列として解釈しこの順に連結して得られる文字列を $z$ とする。
    • $z$ を十進表記の整数として解釈したときの値を $f(x,y)$ とする。
  • たとえば $f(3,14)=314,\ f(100,3)=1003$ です。
  • 正の整数 $C, D$ が与えられます。以下を満たす整数 $x$ の個数を求めてください。
    • $1 \leq x \leq D$
    • $f(C, C+x)$ は平方数である
  • $T$ 個のテストケースが与えられるので、それぞれについて答えを求めてください。

制約

  • $1 \leq T \leq 3 \times 10^5$
  • $1 \leq C \leq 2 \times 10^8$
  • $1 \leq D \leq 5 \times 10^9$
  • 入力される値はすべて整数

解法

一見わかりづらいけど、ABC428にちなんだ問題。
$428^2=183184$ となり、平方数が連続した2数を結合した見た目になる。よくこんなの見つけるもんだ。

$C+x$ の桁数 $d$ を全て試す。$d$ は $((C+1)の桁数)~((C+D)の桁数)$ の範囲、高々 $10$ 通りを試せばよい。

その時、$d$ 別の $f(C,C+x)$ が取り得る値は連続した範囲となり、最大値・最小値は以下のようになる。

(例) C=123  D=12345

d=3  f(C, C+x) の最小値: 123124
     f(C, C+x) の最大値: 123999
d=4  f(C, C+x) の最小値: 1231000
     f(C, C+x) の最大値: 1239999
d=5  f(C, C+x) の最小値: 12310000
     f(C, C+x) の最大値: 12312468

つまり、$C$ の後に付ける数として、

  • 最小値
    • $d$ が $C$ の桁数と一致する場合は、$C+1$
    • それ以外の場合は $100...0$
  • 最大値
    • $d$ が $C+D$ の桁数と一致する場合は、$C+D$
    • それ以外の場合は $999...9$

となる。この範囲の値なら自由に取れる。

自身を2乗するとこの範囲になるような整数 $k$ は、$d$ における最小値を $m_d$、最大値を $M_d$ として、

  • $\left\lceil \sqrt{m_d} \right\rceil \le k \le \left\lfloor \sqrt{M_d} \right\rfloor$

の範囲の任意の整数となるので、$d$ ごとに $O(1)$ で答えが求められる。

$m_d,M_d$ は最大 $2 \times 10^{18}$ を超えうるので、平方根を取る場合は演算誤差に注意する。

Python3

E - Farthest Vertex

問題文

  • $N$ 頂点の木があります。各辺の長さを $1$ とします。
  • $v = 1, 2, \dots, N$ について次の問題を解いてください。
    • 頂点 $1, 2, \dots, N$ のうち頂点 $v$ からの距離が最大となる頂点の番号を出力してください。
    • ただし、条件を満たす頂点が複数存在する場合は 最も番号が大きい頂点 を出力してください。

制約

  • $2 \leq N \leq 5 \times 10^5$
  • $1 \leq A_i \lt B_i \leq N$
  • 入力で与えられるグラフは木
  • 入力される値は全て整数

解法

実装量が多くなりがち。がんばる。

まず、木の直径と中心を計算する。

中心が頂点の場合

中心を根とした木を書く。
根からの距離が半径と等しい頂点の最大番号を、根からの部分木毎に求める。

      ①
  / /  \ \
②  ④  ⑦  ⑨
|  /\  |
③ ⑤⑥ ⑧

↑  ↑  ↑  ↑
③  ⑥  ⑧  なし

この中で最大なのは⑧、次いで⑥である。
⑧を含む部分木の頂点は⑥が答え、それ以外の頂点は⑧が答えとなる。

中心が辺の場合

大体さっきと同じだが、中心を挟む2頂点のそれぞれを根として(中心の辺は削除して)、 根からの距離が半径((直径-1)/2)と等しい頂点の最大番号を求める。

  ①---×---②
 /\      /\
③  ⑤    ⑧  ⑩
|  /\    |
④ ⑥⑦   ⑨
  
  ↑        ↑
  ⑦        ⑨

互いに答えは相手側の最大番号となる。(①の部分木は⑨、②の部分木は⑦)

Python3

解法2

全方位木でも解ける。

最初に適当に根を決め、(自身を含めた)自身から最も遠い頂点への距離と最大頂点番号を、各頂点に付き計算する。

次に、根から親の情報を伝播しつつ渡していく。

F - Pyramid Alignment

問題文

  • 数直線上に $N$ 個の区間があり、$1$ から $N$ までの番号が付けられています。
  • 区間 $i$ の左端の座標は $0$、右端の座標は $W_i$ です。ここで、$W_1 \lt W_2 \lt \dots \lt W_N$ です。
  • $Q$ 個のクエリが与えられるので、与えられた順に処理してください。クエリは次の $3$ 種類のいずれかです。
    • タイプ $1$ ('1 v'): 現在の、区間 $v$ の左端の座標を $l$ とする。番号が $v$ 以下であるすべての区間をそれぞれ、左端の座標が $l$ となるように平行移動する。
    • タイプ $2$ ('2 v'): 現在の、区間 $v$ の右端の座標を $r$ とする。番号が $v$ 以下であるすべての区間をそれぞれ、右端の座標が $r$ となるように平行移動する。
    • タイプ $3$ ('3 x'): 座標 $x+\frac{1}{2}$ を含む区間の現在の個数を出力する。

制約

  • $1 \leq N \leq 2 \times 10^5$
  • $1 \leq Q \leq 2 \times 10^5$
  • $1 \leq W_i \leq 10^9$ ($1 \leq i \leq N$)
  • $W_1 \lt W_2 \lt \dots \lt W_N$
  • タイプ $1,2$ のクエリで与えられる $v$ について、$1 \leq v \leq N$
  • タイプ $3$ のクエリで与えられる $x$ について、$0 \leq x \leq 10^9$
  • タイプ $3$ のクエリは少なくとも $1$ つ与えられる
  • 入力される値はすべて整数

解法

クエリ操作によって区間は動いてしまうが、てんでバラバラにはならず、ある程度規則的な形になる。

  • 区間 $1~a$ は左端が揃っている
  • $a~b$ は右端が揃っている
  • $b~c$ は左端が揃っている
  • …(以下、左右交互)
1       |-|
        |---|
a       |-----|
      |-------|
    |---------|
b |-----------|
  |--------------|
  |----------------|

また、区間 $i$ は常に区間 $i+1$ に内包されるようにしか動かないので、 タイプ3のクエリは、ある境界 $i$ があり 「区間 $i$ 未満は全て $x$ は範囲外」「区間 $i$ 以上は全て $x$ は範囲内」というような形になる。

左右が切り替わる区間番号 $a,b,...$ とその時の左端または右端座標さえ記録しておけば、 この境界を二分探索することによってクエリに答えられる。

$(切り替わる区間番号, 左右どちらで揃うか, 揃う方の座標)$ を、 区間番号の降順にスタックに積む、などの実装で $O(Q\log{N})$ または $O(Q\log^2{N})$ で解ける。

Python3

G - Necklace

問題文

  • $N$ 種類の宝石があります。各宝石は無限にあり、同じ種類の宝石同士は区別できません。
  • $i$ 種類目の宝石の美しさは $b_i$ です。($b_i \ge 2$)
  • $2 \leq x \leq U$ を満たす整数 $x$ について、以下の問題の答えを $f(x)$ と置きます。
    • あなたはいくつかの宝石を円形状に並べてネックレスを作ることにしました。
    • 使用した宝石の美しさの総積が $x$ になるようなネックレスの個数を $998244353$ で割った余りを求めてください。
    • ただし、$2$ つのネックレスは、
      • 回転させて一致する時は同じネックレスとみなして $1$ 回だけ数えます。
      • 回転だけでは一致しないが、上下をひっくり返した上で回転させると一致する場合は、別々に数えます。
  • $f(2), f(3), \dots, f(U)$ を計算してください。

制約

  • $1 \leq N \leq 5 \times 10^5$
  • $2 \leq U \leq 5 \times 10^5$
  • $2 \leq b_i \leq U$
  • 入力される値は全て整数

解法

制約から、ネックレスに使う宝石の個数は $\log{U} \le 18$ 個以下であるとわかる。

  • $F(i,j):=i$ 個の宝石を使って美しさの総積が $j$ 個になるような「宝石の並べ方の個数」

回転による同一視を考慮しない場合の数は、 「$C_k:=(b_i=k)$ である宝石の個数」を掛け合わせていくことによって、 $O(U\log^2{U})$ で求められる。

                        2  3  4
b = (2 2 3 4)  →  C = (2  1  1)

          2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18
i=1       2  1  1

i=2  2*?        4     2     2
     3*?              2        1        1
     4*?                    2           1           1
    --------------------------------------------------------
                4     4     4  1        2           1

i=3  2*?                    8           8           8     2
     3*?                                4                 4
     4*?                                            4
    --------------------------------------------------------
                            8          12          12     6

回転による同一視を考慮すると、大半の並べ方は(宝石の個数)ずつ重複して数えられているが、 周期性があるものについてはその限りではない。

abcacbaab  →  bcacbaaba など、回転して同じになるものが F に9個ずつ数えられている

abcabcabc  →  3つシフトさせると自身と重なるので、同じものは3個しか重複していない。

よって、最短の周期ごとに区別して数えたい。

  • $G(i,j):=i$ 個の宝石を使って美しさの総積が $j$ 個になるようなネックレスのうち、最短周期が $i$ であるようなものの個数
    • ※$G$ は回転による同一視を考慮

$G(i,j)$ で作れるネックレスの宝石の並びを2周期繰り返すと $F(2i,j^2)$ に数えられる並びとなる。3周期だと $F(3i,j^3)$ となる。 このようなものは $G(i,j)$ からの派生で数えるものとし、$F(2i,j^2),F(3i,j^3),...$ からは除くものとする。

よって逆に、$F(i,j)$ から、$i=ki', j=j'^k$ となるような $(i',j',k)$ につき、$G(i',j') \times i'$ を除いていく。
残ったものが最短周期が $i$ である並びとなり、$i$ で割ったものが $G(i,j)$ となる。

  • $\displaystyle G(i,j)=\frac{F(i,j)-\sum_{\{i',j'|ki'=i,j'^k=j\}}G(i',j')\times i'}{i}$

これで、回転による重複を除いて数えることができる。

答えは、各 $G(i,j)$ につき、$j^k \le U$ となるような最大の $k$ に対し $k \times G(i,j)$ を足し合わせた数となる。

Python3

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