trsing’s diary

勉強、読んだ本、仕事で調べたこととかのメモ。

ABC093 D - Worst Caseメモ

問題

f:id:trsing:20200711111311p:plain

D - Worst Case

考えたこと

ペアの組み合わせとしては[1 \cdots \sqrt{AB} ) [1 \cdots \sqrt{AB} ) [1 \cdots \sqrt{AB} ) [\sqrt{AB} \cdots だけど後者のペアをなるべく作ればペアの数を増やせる。

前提条件

 r \leq s,\,\, rs \lt AB,\,\,\,B \lt A

1: (r-i)(s+i)=rs-(s-r)i-i^{2} \leq rs \lt AB (0 \leq i)

r-i=B のとき (r-i)(s+i)=B(s+r-B)\lt AB
よって
 r-b \lt A-s

r= \lfloor \sqrt{AB} \rfloor とおく

rが平方数の場合

r*r=ABなのでrの組を作れません。r未満は使用できるのでr-1個の組を二つ作れます*1

  • A \neq Bの場合、A,Bが使えなため-1 *2してr-1+r-1-1f:id:trsing:20200711112017p:plain
  • A=Bの場合はそのままr-1+r-1 f:id:trsing:20200711111956p:plain

rが平方数でない場合

  • r(r+1)\lt ABの場合、r個の組を二つ作れます。 f:id:trsing:20200711112048p:plain
  • そうでない場合、r個の組とr-1個の組を作れます*3f:id:trsing:20200711112109p:plain A,Bが使えないため-1。 よって前者はr+r-1 後者はr+r-1-1

コード

static long Calc(long A, long B)
{
    if (A == B)
        return A - 1 + B - 1;

    var lim = A * B;
    var r = (long)Sqrt(lim);
    if (lim < r * r) --r;
    if ((r + 1) * (r + 1) < lim) ++r;
    if (r * r == lim)
        return r - 1 + r - 1 - 1;
    var a = r + r - 1 - 1;
    if (r * (r + 1) < lim)
        ++a;
    return a;
}

背景

わーいO(1)でクエリ処理できたメモっとこー と思ったけど\sqrt{AB}を求める計算量それなりにあるよね・・・

よく読んだら解説と同じ方法っぽいことに気づいた。

その他

(1,AB/1-1),\,\,(2,AB/2-1),\cdotsをペアにできてここから考えると見通しよさそうな気配。あ、途中でAB/i=AB/(i+1)みたいなの出てくる・・・。

被らない条件を考えると 1 \leq AB/i-AB/(i+1)になればいいから \sqrt{AB}まで大丈夫か。・・・あっ(察し。

みたいな感じで上記解法に至りました。

*1:①の条件から

*2:②の条件から1引くだけで十分

*3:r*r \lt ABなのでrの組を使用できる