はじめに
405Eの解答を読み込んでいる際に、珍しいものを目の当たりにしました。
関数の中に関数が定義されているではありませんか。
それについて調べたことをまとめています。
無名関数とは
いいとこ:
・スコープが限定されているから全体が見やすくなる
・その関数内でのみ使う処理ならそこのみ定義してあげた方が親切
・引数として渡す量が減る 関係変数をグローバルにしなくても使える
・変数のような扱いなので最適化がしやすい(最重要)
わるいとこ:
・他の関数では再利用できない :(
詰まるところ、競プロ向けというわけです。
別の用途もたくさん存在するそうですが、疎い知識で話したところで、正確な情報を提供できる望みは薄いため、詳しいことはコメント欄にて有識者さんのをご確認くだ
文法
定義(繰り返し二乗法)
auto exp = [&](int base, int e) {
int ans = 1;
while(e) {
if(e & 1) ans = ans * base % MOD;
base = base * base % MOD;
e >>= 1;
}
return ans;
};
通常の関数定義とは違い、()の手前に[]があることが特徴です。
これは外部変数へのアクセス所有権を決める属性のような場所です。
- &: 中で起きた数値変化が外にも適用される
- =: 外の変数値をコピーするだけ
他にもあるかもしれませんが、筆者の知識の限界をお許しください。(編集リクエスト通します)
呼び出し
inv[MAXN] = exp(fact[MAXN], MOD - 2);
同じスコープ内で、こんな具合に呼び出します。これは通常の関数制御と完全一致していますね。
まとめ
色んな関数の呼び出し方を知っておけば、あらぬところで効率化できるので、スポンジのごとく吸収しちゃいましょう。
ここまでお疲れ様でした!