日曜日、ロシアコードカップのトレーニングウォームアップラウンドが行われました。 最初の場所は、ペルミのミハイル「mmaxio」マヨロフによって撮影されました。 第二-モスクワからイゴール「kraskevich」Kraskevich。 第三-モスクワのバレンタイン「ValenKof」コフマン。 受賞者の皆さん、おめでとうございます!
チャンピオンシップの予選ラウンドを控えています。 最初の予選ラウンドは3月28日18:00モスクワ時間に開催され、選手権への登録は3回目の予選ラウンドが始まる前にサイト
http://www.russiancodecup.ru/で行われます。
ロシア語コードカップは、ロシア語を話す世界中のプログラマーがスキルをテストし、さまざまな複雑さの元の問題を解決することで習熟度を実証する機会であると同時に、専門のITコミュニティに表明する機会でもあります。 オリンピアードは3段階で行われます:予選ラウンド、予選ラウンド、決勝-それぞれ4から8つの多様なタスクがオリンピアードの参加者に提供されます。 コンテストのタスクと技術部分は、ロシアコードカップの共同主催者であるMail.Ru Groupの専門家とITMO大学の専門家によって提供されます。
次に、ウォームアップラウンドの問題の解決策を説明します。
問題A. バルーン
配列内の異なる数の数を見つけます。 それが
k以上の場合、答えで
k個の異なる色をダイヤルできます。
kより小さい場合、各色のボールを1つ取り、不足しているボールを勝手に取ります。 並べ替えることで、配列内のすべての異なる番号を見つけることができます。
タスクB. テスト購入
タスクでは、条件に記述されているプロセスをシミュレートする必要がありました。 ボックスを複製します。たとえば、2つの支払い方法を持つ1つのボックスではなく、異なるコストの2つのボックスがあり、そのうち1つしか購入できません。 タイムイベントで並べ替え:現金領収書とボックス。 さらに、最も近い領収書とボックスの時刻が同じ場合、領収書を優先します。 入金イベントごとに、受け取った金額を現在の金額に追加するだけです。 まだ購入していない箱の外観のイベントごとに、十分なお金があるかどうかを確認し、ある場合は箱を購入します。
タスクC. 厳emなパレード
k> n 2または最大10
7までの素数が
kより小さい場合、解はありません。他の場合には解があります。
n = p1 s1 ×p2 s2 ×...×pk skの約数の数が
(s 1 +1)×(s 2 +1)×...×(s k +1)であるという事実を使用します。
各行と各列で素数のべきのセットが等しくなるように、つまり、それらの数が
p1 s1 ×p2 s2 ×...×pk skという形式になるように行列を生成します。ここで、
piはいくつかの素数です。各行と列、および
s iは、すべての行と列の固定数です。
k> nの場合、次のように
n 2- (k-n)マトリックスセルを埋めます。最初の
nプライムの
i番目の巡回シフトでマトリックスの
i番目の行を埋め、残りの
k-nプライムでマトリックスの残りの
k-nセルを埋めます。 したがって、各行と各列には正確に
n個の異なる素数があり、それらの除数の数は同じになります。
k≤nの場合、マトリックスの
a [i] [j]番目のセルに
(i + j)mod k番目の素数を入れます
(ゼロからインデックス付けする場合)。 この充填が目的の結果をもたらすことを確認できます。
タスクD. 手下は楽しい
条件を次のように再定式化します。無向グラフで、最小エッジと最大エッジの重みの合計が最大になるサイクルを見つける必要があります。 まず、関数
\ emph {≥xの問題に対する答えが単調
であることは事実ですか?に注意してください。 そのため、バイナリ検索を実行できます。 問題に対する答えが
≥xであることを確認する方法は?
すべてのエッジから
x / 2を引きます。 ここで、最小エッジと最大エッジの合計が0より大きいサイクルの存在を確認する必要があります。非負の重みを持つ最小エッジを取り、その重みを
w 1とします。 データ構造
\ emph {非結合セットのシステム}に 、重みが
-w 1を超えないすべてのエッジを追加します。 その後、エッジ
w 1を追加します。 追加するときに、エッジの端が同じ接続コンポーネント内にある場合、必要なサイクルが見つかりました。そうでない場合は、まだ存在していません。
この後、アルゴリズムを続行します-重み
w 2で次の非負のエッジを取得し、重み
-w 2 .. -w 1 -1ですべてのエッジを追加し、エッジ
w 2自体を追加します。 追加するときに、エッジの端が同じコンポーネントにあった場合、サイクルが見つかりますが、そうでない場合はまだありません。 すべての非負のエッジに対してアルゴリズムを実行し続けます。
タスクE. 宝くじ
すべての
x iが異なる場合、最初に問題を解決します。 リクエストを昇順
x iでソートします。 あらゆる瞬間に、配列のどの要素が既にある数で占められているかを知りたい。 最初は、配列の単一の要素がビジーではありません。
配列ができました。いくつかの要素がその中にあります。 応答が
x iであるリクエストを処理します。
x j <x iがすでに処理されているすべての
x jに対する要求。 セグメント
l i ..r iの占有されていない要素の数を計算します。
cntにします 。 次に、これらのすべての要素に数値を入れて、答えに
x icnt- (x i -1)を掛けると
言います。cntは
cnt番号の順序セットの数で、少なくとも1つの数値は
x iに等しくなります。 これらの要素に
x iより大きい数を入れることはできません(この場合のリクエストへの応答は
x iと等しくなりません)。 したがって、配列は失われませんでした。
すべてのリクエストを処理した後、配列の空の要素に任意の数字を入れることができます。 したがって、答えに
k cntを掛け
ます 。
完全なソリューション:前のケースと同じ方法で問題を解決します。 これで
x iを同じにすることができます。 答えが
xであるクエリの問題を解決します。 他のセグメントを含むすべてのセグメントを考慮から削除します。 残りの部分では、ダイナミクスをカウントします
。dp [i] -長さ
iのプレフィックスに番号を配置して、番号
xが最後になるようにする方法の数。 次に、最後に番号
xが検出された位置を反復処理する必要があり、それを位置
j (
jと
iの間の残りのセルでは厳密に
xより小さい)にしますが、セグメントを見逃さないようにする必要があります。 つまり、そのようなセグメント(
l、r )が存在せず、答えが
xであり、
j <l≤r <iであるということです。 この場合、
xは表示されません。
したがって、
dp [i] = sum(j = k..i-1:dp [j](x-1) i-j-1 、ここでkはセグメントの左境界で、その右境界は位置
iとその左にあります最後は位置
iに最も近く、そのようなダイナミクスは
O(nm)に対して全体的に機能します。
位置
iの k値は、位置
i-1に何らかのセグメントの終わり
があった場合にのみ、位置
i-1と比較して変化することに注意してください。 位置
i-1にセグメントの正しいグラジツァがなかった場合、
dp [i] = dp [i-1]×(x-1)+ dp [i-1] = dp [i-1]×x したがって、2つの隣接する右境界線間のダイナミクスの値を
x cntとして考慮することにより、漸近性の乗数
nを取り除くことができ
ます 。ここで、
cntは何かを置くことができる場所の数です。
結果のソリューションは
O(m log n + n)で機能します。