主客転倒について
コストの寄与を考える

※本稿を執筆しているのは競プロ初心者であるため、読みづらかったり間違いを含んでいる可能性があります。ご了承下さい。またABCの過去問のネタバレを含んでいます。
競プロの問題の典型に、盤面に対してコストが設定されるときあらゆる盤面に対してコストを計算しその和を出力せよ、というものがある。例えば以下のような問題。
例題
長さの数列が与えられる。うぇかりー君は数列から連続した部分列を選ぶのが好きであり、数列からを選んだときうぇかりー君の喜び度はと定義される。数列のあらゆる連続した部分列の選び方に対してうぇかりー君の喜び度を計算しその和をで割った余りを出力せよ。
制約
例題に対する入力としてが与えられたとすると、に対する連続した部分列の選び方は、(何も選ばない)、、、、、で全てであり、答えはとなる。
長さに関する制約から選び方をすべて列挙して計算するのはかかって厳しい。なので、かわりにを含む連続する部分列の選び方が何通りあるかを数える。が含まれる連続する部分列の個数は個であるので、答えのコストのうちが選ばれることによるコストはとなる。よって例題の答えは以下のコードで計算出来る。(入力は省略)
const int MOD = 1e9+7;
long long ans = 0;
int n;
vector<long long> a(n);
for(int i = 0;i < n;i++){
ans += a[i] * (i+1) % MOD * (n-i) % MOD;
ans %= MOD;
}
cout << ans << endl;
答えに含まれる回数などを数え上げることで計算量をへらすのは典型でABCの過去問にもちょこちょこあったりするので、なんとなく覚えておくといいかもしれません。
類題:ABC058-E ABC127-E
ブログの更新をお知らせ
RSS リーダーに登録すると、新しい記事が公開されたときに通知を受け取れます。



