タイトル説明
それは長さ有し\(N- \)配列を、初期シーケンス番号が全て(2 ^ {31} -1 \)\。
そこ\(M \)操作、\(I \)第一の配列のための操作\(a_iを\)に対する改変の数\(B_i \) 。
-記録\(I \)最小時間の動作シーケンスの後に\(S_I \)は、出力する必要がある(SUM \ limits_ \ 1} = {I ^ MのS_I \ 10099タイムズ^ I \)\。
\(a_iを\)と\(b_i \)以下の方法により決定されます。
输入整数\(X_0 \) 、\(X_1 \) 、\(\) 、\(B \) 、\(C \)、令\(X_I =(ax_ {I-2} + bx_ {I-1 } + C)\ 2 ^ {32} \クワッド(I \ GE 2)\)BMOD、则\(a_iを= \左\ lfloor \ dfrac {X_ {2I-1}}、{4} \右\ rfloor \ BMODをN \)、 \(b_i = \左\ lfloor \ dfrac {X_ {2I}} {4} \右\ rfloor \)。
入力形式
行7つの整数\(N- \)、\ (M \)、\ (X_0 \)、\ (X_1 \)、\ (A \) \ (B \)、\ (C \) 。
出力フォーマット
整数回答の列。
データ範囲
試験時間制限\(\ 1000 \ mathrm MS {} \) 、スペースの制約\(256 \ \ mathrmのMIB} {\) 。
- 以下のための\(10 \%\) 、データ\(1 \ N-LE、M \ル\ 1000。) 。
- 用(50 \%\)\、データ\(1 \ N-LE、M \ル5 ^ 10 \。) 。
- 以下のための\(100 \%\)データ、\(1 \ルN-、M \ル10 ^ 7 \)、\ (X_0 \)、\ (X_1 \)、\ (A \) \ (B \)、\ (C \)で\(\左[0,2 ^ { 31} -1 \右)\) 一様にランダム。
分析
私たちは、より大胆なアプローチのいくつかを考慮しなければならないので、この問題は、小規模な操作が必要であることに注意してください。
\(\ Mathtt {10の\ PTS} \)
非常に単純な、アレイ、各修飾後続スキャン再び暴力の最小複雑記録\(シータ(1 \)。 - \シータ(N)\) 、しっかりタイムアウト。
\(\ Mathtt {50の\ PTS} \)
それだけ設定も非常に簡単である\(\ mathcal {O}( \ Nログ)\) のデータ構造のメッシングライン。
\(\ Mathtt {100の\ PTS} \)
それを少し難しいと思いました。
データ範囲によると、我々はおそらく、クエリ設計する\(\シータ(1)\ ) アルゴリズムを。それは簡単な変更です\(\シータ(1)\) 、クエリ\(\シータ(1)\) 。
脳は、クエリをサポートするように見える変更、それを略奪した後、変更がある\(\シータ(1)\ ) だけ暴力的です。
しかし、一般的対象に、癌は、クエリ時に非常に反応しなく実行するために、設計データカード暴力的な人々の話題になります。
しかし......私たちは、この問題の操作は、擬似ランダムに生成されました。です......
このアルゴリズムを考えてみましょう:
メンテナンスアレイ\(A \) 、レコード\(I \)ビットの値\(a_iを\) 。
レビュー:直接変更(a_iを\)\ ;
クエリ:
位置は、ここで最小値、最小値ではなく、それらの位置を更新します。
もしそうなら、その後、最小更新暴力。
確率の最小値に対する変更の擬似ランダム性質\(\ dfrac {{N-M}} \)次に、数学的期待値の複雑
[\ {整列}開始E \ (X)&= \ dfrac {M} {N} \倍\ mathcal { O}(N)+ \左(M- \ dfrac {M} {N} \右)\回\ mathcal {O}(1)\\&= \ mathcal {O}( M)+ \ mathcal {O} (M)\\&= \ mathcal {O}(M)\端{整列} \]
この質問によって。
コード
ところで、この質問はほとんどのカード......オープンスペースlong long
爆撃に。
#include <cstdio>
#include <climits>
using namespace std;
typedef unsigned int ui;
const int max_n = 10000000;
const ui mul = 10099;
ui nums[max_n];
int main()
{
int n, m, min_pos = -1;
ui x0, x1, a, b, c, ans = 0, tk = 1, xt, ai, bi, min_val = INT_MAX;
scanf("%d%d%u%u%u%u%u", &n, &m, &x0, &x1, &a, &b, &c);
for (int i = 0; i < n; i++)
nums[i] = INT_MAX;
for (int i = 0; i < m; i++)
{
ai = (x1 / 4) % n;
xt = a * x0 + b * x1 + c;
bi = xt / 4, x0 = x1, x1 = xt;
xt = a * x0 + b * x1 + c;
x0 = x1, x1 = xt;
nums[ai] = bi;
if (ai == min_pos && bi > min_val)
{
min_val = INT_MAX, min_pos = -1;
for (int i = 0; i < n; i++)
if (nums[i] < min_val)
{
min_val = nums[i];
min_pos = i;
}
}
else if (bi < min_val)
{
min_val = bi;
min_pos = ai;
}
tk *= mul;
ans += tk * min_val;
}
printf("%u\n", ans);
return 0;
}
追伸
より複雑なアプリケーションの広い範囲 - この質問は私たちに非常に興味深い理由を伝えます。
同様に、複雑度が小さい、範囲が小さくなります。
場合問題解決、一般に、対象の範囲内、すなわち、適切なアルゴリズムを選択し、複雑性が良好です。この質問は良い例です。