geam1113’s diary

主にAtcoderのコンテストの備忘録を書きます。AtCoder緑と水色を行ったり来たりしています。

ARC137 参加記録

コンテスト中AC:なし
A,B解説AC

A - Coprime Pair

公式解説

素数の間隔(prime gap)が重要とのことです。

素数の間隔 - Wikipedia

公式解説及び上記のwikiによれば、問題の制約における素数間の極大の間隔(maximum gap)は1500らしいです。

よって、L\leq x \leq L+1500及びR-1500 \leq y \leq Rを満たす組(x,y)のうち少なくとも1つはx,yがいずれも素数である組が存在するということでした。

d=y-xとすると、R-L-3000\leq d \leq R-Lの範囲だけgcd(x,y)=1となる組を調べれば良くなり、全探索可能になるということでした。

提出コード

B - Count 1's

  • コンテスト中にたどり着いた部分

連続した部分列の0の個数をS^0、1の個数をS^1、初期状態における1の個数をXとすると、操作後の1の数をX+S^0 - S^1にできます。

また、S=S^0 - S^1の最大値をS_{max}とし、その時の連続した部分列の区間を閉区間[l,r]とします。

区間が空の状態から、+1ずつ伸長して[l,r]にした時、Sも+1ずつしかされないので、S=0,1,\cdots ,S_{max}にできます。

最小値S_{min}についても同様です。
従って、Sは、S_{min}\leq S \leq S_{max}を満たす全ての整数にすることができます。

以上から、S_{min}\leq S \leq S_{max}に0を含むならS_{max} - S_{min} +1が答えとなります。
0を含まないなら、空の部分列を選ぶと0にもできるので、S_{max} - S_{min} +2となります。

  • コンテスト中わからなかった部分

S_{min},\ S_{max}の求め方がわかりませんでした。
公式解説によれば簡単に求められるとなっていました。

区間[1,i]の部分列に含まれる0の個数をS^0_i、1の個数をS^1_iとします。

[i,j]に含まれる0の個数はS^0_i - S^0_{j-1}、1の個数はS^1_i - S^1_{j-1}です。
よって、[i,j]S^0 - S^1は以下のように計算できます。
S^0_i - S^0_{j-1} - (S^1_i - S^1_{j-1}) = S^0_i - S^1_i - (S^0_{j-1} - S^1_{j-1})

従って、iを末尾とする連続した部分列のS^0 - S^1が最大となるのは、0\leq j \lt iを満たすjのうち、S^0_j - S^1_{j}が最小となるもの選んだ場合です(便宜上、 S^0_0 - S^1_0= 0)。
同様に、S^0 - S^1が最小となるのは、S^0_j - S^1_{j}が最大となるもの選んだ場合です。

よって、i=1,\ 2,\ \cdots ,\ Nについて、S^0_i - S^1_{i}を順次計算し、最大値と最小値を管理しておくことで、O(1)で各iを末尾とした時の連続した部分列のS^0 - S^1の最大・最小を求められます。

以上から、S_{min},S_{max}O(N)で求められます。

提出コード