−目次
AtCoder Regular Contest 200 (Div. 2) A,B,C,D,E問題メモ
A - Dot Product
問題文
- 長さ N の正整数列 A=(A1,A2,…,AN),B=(B1,B2,…,BN) が与えられます。
- 以下の条件を全て満たす整数列 X=(X1,X2,…,XN) が存在するか判定し、存在するなら一つ求めてください。
- −108≤Xi≤108 (1≤i≤N)
- N∑i=1AiXi>0
- N∑i=1BiXi<0
- T 個のテストケースが与えられるので、それぞれについて答えを求めてください。
制約
- 1≤T≤2×105
- 1≤N≤2×105
- 1≤Ai,Bi≤105
- 全てのテストケースにおける N の総和は 2×105 以下
- 入力される値は全て整数
解法
C=N∑i=1AiXi, D=N∑i=1BiXi とする。
N=1 のとき
Ai,Bi は正より、C,D も両方正か両方負にしかできないので不可能。
N=2 のとき
(Ai,Bi) を gcd(Ai,Bi) で割って、互いに素にしたものを (A′i,B′i) とする。
(A′1,B′1)=(A′2,B′2) の時は不可能である。
(C,D) が取り得る領域は y=B1A1x 上の直線上にしか存在せず、この直線は第1と第3象限しか通らない。
それ以外の時、以下のようにできる。
A 20 25 B 31 41 まず、Aを揃える。 X 25 20 AX 500 500 BX 775 840 この例では BX1 < BX2 なので、X=(25,-20) とすれば、C=0, D<0 にできる。 また、Bを揃える。 X 41 31 AX 840 775 BX 1271 1271 この例では AX1 > AX2 なので、X=(41,-31) とすれば、C>0, D=0 にできる。 そしてこれは線形的に合成できるので、 X=(25+41, -20-31) とすれば、C>0,D<0 にできる。 X 66 -51 AX 1320 -1275 → C = 45 > 0 BX 2046 -2091 → D = -45 < 0
大小関係が逆の場合は符号が逆になる。
−2×105≤−(Amax+Bmax)≤Xi≤(Amax+Bmax)≤2×105 より、値の範囲も大丈夫。
N≥3 のとき
B - LCM
問題文
- 正整数 A1,A2,A3 が与えられます。
- 以下の条件を全て満たす正整数の組 (X1,X2) が存在するか判定し、存在する場合は一組求めてください。
- X1 は十進法で A1 桁の整数である。
- X2 は十進法で A2 桁の整数である。
- X1 と X2 の最小公倍数は十進法で A3 桁の整数である。
- T 個のテストケースが与えられるので、それぞれについて答えを求めてください。
制約
- 1≤T≤173
- 1≤A1,A2,A3≤17
- 入力される値は全て整数
解法
互いに素な X1,X2 なら、最小公倍数は X1×X2 になるので桁数がわかりやすい。
そういう方向に持ってけないか考える。
a 桁× b 桁は、a+b−1 または a+b 桁となる。
a=4, b=5 最小: 1000 * 10000 = 10000000 →8桁 最大: 9999 * 99999 = 999890001 →9桁
最小公倍数は2数の積より大きくはならないので、A1+A2<A3 なら不可能。
また、最小公倍数は元の数より小さくならないので、A1>A3 や A2>A3 の場合も不可能。
それ以外の場合、互いに素であることが保証される素数を使って、構築できる。
直接的に A1+A2=A3 または A1+A2=A3−1 という関係性に無い場合は、末尾に0を追加して調整する。
xはa桁、yはb桁、x,yは互いに素、z=xy LCM( x0000 , y0000 ) = z0000 ~~~~~ ~~~~~ ~~~~~ a+4桁 b+4桁 a+b+4 または (a+b-1)+4 桁
A1+A2−1≤A3≤A1+A2 になるまで、A1,A2,A3 から1ずつ引いていく。
この時引いた回数を d、引いた結果を A′1,A′2,A′3 として、X1,X2 は以下のように作れる。
- A′3=A′1+A′2−1 の時
- X′1=A′1 桁の最小の素数
- X′2=A′2 桁の2番目に小さい素数
- A′3=A′1+A′2 の時
- X′1=A′1 桁の最大の素数
- X′2=A′2 桁の2番目に大きい素数
- X1=X′1 の末尾に0を d 個追加したもの
- X2=X′2 の末尾に0を d 個追加したもの
この方法で X′1×X′2 が A′3 桁となり、X1×X2 が A3 桁となる。
素数はわりと密に存在するので、各桁の最小や最大(1000 や 9999 など)から多少ずれたとしても、積の桁数が変わるほどずれることはない。
「k 桁の最小・最大の素数」を得るには、Pythonなら sympy.nextprime, prevprime が使える。
C - Movie Theater
問題文
- 正整数 N と長さ N の正整数列 L=(L1,L2,…,LN),R=(R1,R2,…,RN) が与えられます。
- ここで、 L1,L2,…,LN,R1,R2,…,RN は全て互いに異なることが保証されます。
- ある映画館には N 個の席が左右一列に並んでいます。左から i 番目の席を席 i と呼びます。
- この映画館に人 1 から人 N までの N 人の人が訪れます。あなたは各人に席を 1 つずつ割り当てます。
- 人 i に割り当てた席を Pi とすると、人 i は時刻 Li に席 1,2,…,Pi−1 を横切って席 Pi に座り、時刻 Ri に席 1,2,…,Pi−1 を横切って席から離れます。
- 人 i の 不満度 を時刻 Li から時刻 Ri までの間(ちょうど Li,Ri は含まない)に他の人に席 Pi を横切られた回数とします。
- 人 1 から人 N までの N 人の不満度の総和が最小となる (1,2,…,N) の順列 P のうち辞書順最小のものを求めてください。
- T 個のテストケースが与えられるので、それぞれについて答えを求めてください。
制約
- 1≤T≤500
- 1≤N≤500
- 1≤Li<Ri≤2×N
- L1,L2,…,LN,R1,R2,…,RN は全て互いに異なる
- 全てのテストケースにおける N の総和は 500 以下
- 入力される値は全て整数
解法
答えが逆(シート i に誰を座らせるか)という問題だったらトポロジカルソートで簡単に求まるのに、、、
「人 i をどのシートに座らせるか」を辞書順最小にするのに意外と手こずった。
[Li,Ri] を数直線にプロットし、その関係性を3種類に場合分けする。
■交わらない |----1----| |---2---| この場合、お互いに不満度を与えることはない。 座らせるシートの左右位置関係はどちらでも良い。 ■交差する |----1----| |----2----| 人1を左に座らせると、人2の入館時に1が不満を1覚える。 人2を左に座らせると、人1の退館時に2が不満を1覚える。 どちらにしろ不満が1増えるのは変わらないので、座らせる位置関係はどちらでもよい。 ■包含する |-------1-------| |----2---| 人1を左に座らせると、人2の入館時と退館時に不満を2覚える。 人2を左に座らせると、不満は増えない。 よってこの場合は、人2を左に座らせないといけない。P2 < P1 となる。
一部の P の値に大小関係の制約ができたが、包含関係のみに由来するのでこの制約は推移的である。
つまり、Pi<Pj かつ Pj<Pk となる (i,j,k) に対し、Pi<Pk が必ず成り立ち、矛盾することはない。
この制約、つまり「入退館時刻が包含関係にある2人は、短い方を左のシートに座らせる」というルールさえ守っていれば、不満度最小は達成できる。
i=1 から、「シートの範囲と、この範囲のシートに座らせる人の集合」を分割していくように貪欲に求めていける。
例えば N=8 で、
- P1>Pi となるような i : {3,5,8}
- P1<Pi、または 1 との制約がない i : {2,4,6,7}
に分けられる場合、人 1 はなるべく左に座らせたい(P1 を小さくしたい)ので、 3,5,8 のみ左に座らせ、人 1 は4番目のシートに座ることになる。P1=4 と決まる。
シートに誰を座らせるか(P の逆順列)の順列を Q とすると、このように部分的に決まる。
i 1 2 3 4 5 6 7 8 Q {3,5,8} 1 {2,4,6,7}
i と Q(ひいては Pi と i)の対応が分割され、左と右で再帰的に同じような問題と見なせる。
たとえば左では、{3,5,8} のうち最小の番号の人が 3 なので、P3 の値を最小にすることを考える。
- {5,8} のうち、P3>Pi となるような i : {8}
- {5,8} のうち、P3<Pi または制約がない i : {5}
だったとすると、以下のように決まる。
i 1 2 3 4 5 6 7 8 Q {8} 3 {5} 1 {2,4,6,7}
このように、グループのうち番号が最小の人の座るシートを決めていくと、O(N2) で解ける。
D - |A + A|
問題文
- 正整数 M,K が与えられます。
- 以下の条件を全て満たす正整数 N と整数列 A=(A1,A2,…,AN) が存在するか判定し、存在するなら一つ求めてください。
- 1≤N≤M
- 0≤Ai<M (1≤i≤N)
- k\equiv A_i+A_j \pmod M を満たす添字の組 (i,j) が存在するような整数 0\le k \lt M がちょうど K 個存在する。
- T 個のテストケースが与えられるので、それぞれについて答えを求めてください。
制約
- 1\le T\le 2\times 10^5
- 1\le K\le M\le 2\times 10^5
- 全てのテストケースにおける M の総和は 2\times 10^5 以下
- 入力される値は全て整数
解法
3つめの条件がちょっと分かりづらいが、要は100ますけいさんのように数列 A を縦と横に書いて足し算(mod)して、 その表に表れる数字の種類数が K 個になるように A を決めよ、と言っている。
| 3 1 4 --+--------- 3 | 6 4 7 2,4,5,6,7,8 の6種類 1 | 4 2 5 4 | 7 5 8
言わずもがな表の値は対角線を挟んで対称なので、右上の部分のみ考える。
いろいろ実験してみる。シンプルに、A=(0,1,2,...) としてみると、
| 0 1 2 3 A=(0,1,...,x) とすると、 --+------------ 0~2x の 2x+1 個の値が現れる。 0 | 0 1 2 3 1 | 2 3 4 2 | 4 5 3 | 6
A=(0,1,2,...,\frac{K-1}{2}) とすることで、K が奇数の場合は必ず構築できるとわかる。
では、K が偶数の場合は?
何となく、\mod{M} を利用することを考えると訳わかんなくなりそうなので、まずはなるべく和が M 未満に収まるようなものを考えたい。
上記の場合は 0~2x の値が使われたが、では、A=(0,2,3,...,x) とすると 1 だけを使わないようにできるのでは?
| 0 2 3 4 5 --+--------------- 0 | 0 2 3 4 5 2 | 4 5 6 7 3 | 6 7 8 4 | 8 9 5 | 10 ┘ ┘ ┘ ┘ ┘ 種類数 1 3 6 8 10
K \ge 6 の偶数なら狙い通りとなり、A=(0,2,3,...,\frac{K}{2}) でできそう。
ただし、K=M の時、たとえば K=M=8 の時、
A=(0,2,3,4) とすると 4+4=8 がmodで 0 になってしまい、7 種類になってしまう。
しかしこの場合は、そもそも 0~M-1 を全て出現させれば良いので、適当に密に作ればよい。
A=(0,1,...,M-1) などがあてはまる。
これを最初に判定して除けば、K \ge 6 の偶数ならできることが分かった。
残るは K=2,4 の時のみ。
愚直ケースを書いて調べると、M が K の倍数の時は、
(0,\frac{M}{K},2\frac{M}{K},...,(K-1)\frac{M}{K}) を和に全て出現させることで達成できることがわかる。
M=12 K=4 | 0 3 6 9 K=M の場合の応用バージョン --+------------ 0 | 0 3 6 9 3 | 6 9 0 6 | 0 3 9 | 6
K=2,4 で M が K の倍数でない時にできない証明がなかなか難しいが、まぁ、愚直でここまで綺麗な法則が現れたら大丈夫やろと信じれば通る。
証明は公式Editorial参照。
まとめると、(上から順に判定して当てはまれば終了)
- M が K の倍数なら、A=(0,\frac{M}{K},2\frac{M}{K},...,(K-1)\frac{M}{K})
- K が奇数なら、A=(0,1,2,...,\frac{K-1}{2})
- K が6以上の偶数なら、A=(0,2,3,...,\frac{K}{2})
- それ以外は不可能
E - popcount <= 2
問題文
- 正整数 N,M が与えられます。
- 長さ N の非負整数列 A=(A_1,A_2,\ldots,A_N) であって、以下の条件を全て満たすものの個数を 998244353 で割ったあまりを求めてください。
- 0\le A_i \lt 2^M (1\le i\le N)
- \operatorname{popcount}(A_i\oplus A_j) \le 2 (1\le i \lt j\le N)
- T 個のテストケースが与えられるので、それぞれについて答えを求めてください。
制約
- 1\le T\le 2\times 10^5
- 2\le N,M \lt 998244353
- 入力される値は全て整数
解法
丁寧な場合分け。
まず、条件を満たす数列 A の各要素に対し 1 以上 2^M 未満の同じ値をXORしたものも、
また別の条件を満たす数列となる。
よって A_1=0 の場合を考えることとし、最終的な答えはそれを 2^M 倍すればよい。
A_1=0 の時、当然、他の全ての要素のpopcountは 2 以下でなければならない。
\max(\operatorname{popcount}(A_i)) \le 1
全ての A_i が、0 または1つだけbitが立っている数列は条件を満たす。
i=2~N につき、A_i の選択肢が M+1 通り、独立にあるので、(M+1)^{N-1} 通り。
\max(\operatorname{popcount}(A_i)) = 2
愚直を書いて観察すると、3パターンに分かれて考えられそう。
- ①ある共通のbit1つと、他に高々1つのbitが立っている場合
- ②\{00,01,10,11\} の4つからなる場合
- ③\{000,011,101,110\} の4つからなる場合
①
こんなやつ
00000000 00001010 00101000 10001000 00001000 00011000 ^ 共通のbit
共通のbit位置が M 通りある。それを固定したとき、A_2~A_{N} に置く数は以下の M+1 通りが選択肢としてあり得る。
- a) 他にどこか立っている M-1 通り
- b) 共通のbitのみが立っている
- c) 0
このうち、「b) または c) のみからなる」ものは、\max(\operatorname{popcount}(A_i)) \le 1 で既に数えられている。
また、「a) または c) のみからなり、a) で共通のbitの他に立てたbitが全てで一致」するものは、 ①の過程で2回ずつ重複して数えられる。
よって、共通bitを固定すると (M+1)^{N-1}-2^{N-1}-\frac{(2^{N-1}-1)(M-1)}{2} の組合せがある。
この M 倍が①の場合の答えとなる。
②,③
補足すると、「\{00,01,10,11\} の4つからなる」とは、M 個中どこか2箇所のbitを選んで、 それが (0,0),(0,1),(1,0),(1,1) のどれか、他は 0 である状態を示す。
どのbitを選ぶかは、②は {}_M C_2 通り、③は {}_M C_3 通りある。
これを固定した場合を考えて、あとで倍加する。
いずれも、4つ全てが出現する場合以外は既に数えられている。
0 は A_1 で必ず出現することに注意して包除原理を適用すると、 A_2 以降の決め方は 4^{N-1} - 3 \times 3^{N-1} + 3 \times 2^{N-1} - 1 通りずつある。
この ({}_M C_2 + {}_M C_3) 倍が、②③の場合の答えとなる。