競技プログラマ、どうせ #define
しか使わなくないか
if の初期化文
if 文の中に初期化文を書けるようになります。 たとえば、よくある DP の例を挙げます。
if (dp[next] > dp[cur] + cost) { dp[next] = dp[cur] + cost; ... }
これは次のように書けるようになります。
if (int tmp = dp[cur] + cost; dp[next] > tmp) { dp[next] = tmp; ... }
うーーん、chmin
を書いた方が楽かな(せめて #define
じゃなくて関数テンプレートを使ってほしい)
tmp
が if の外に漏れないので変なバグを防げたり、同じ式を書かないで済むのはうれしそう。
構造化束縛
pair や tuple からまとめて初期化できます。 たとえば Dijkstra 法で優先度つきキューから取り出すところを考えます。
priority_queue<pair<int, int>, vector<pair<int, int>>, greater<>> pq; ... while (!pq.empty()) { int w = pq.top().first; int v = pq.top().second; ... }
あるいは
while (!pq.empty()) { int w, v; tie(w, v) = pq.top(); ... }
これがこう書けるようになります。
while (!pq.empty()) { auto [w, v] = pq.top(); ... }
これはわりとよさそうみたいなとこない? Dijkstra 自体はぺたりされそうだけど。
クラステンプレートの実引数推定
vector
などのテンプレート引数を省略できる局面があります。
vector<int> a(n, 0);
これをこう。
vector a(n, 0);
え、もしかして
vector a(n1, vector(n2, vector(n3, 0)));
みたいに書けるようになったりしますか? できますね、すごそう。 いや、えびちゃんは適当にテンプレートを使っちゃいます(14 で十分書けちゃうんですけど)。
auto a = make_vector({n1, n2, n3}, 0);
古いのだと地獄を書く必要があることで有名ですね。
vector<vector<vector<int>>> a(n1, vector<vector<int>>(n2, vector<int>(n3, 0)));
clamp
ある値 v
を区間 [lo, hi]
を超えていたらその区間の最小値や最大値まで丸める処理ってたまにないですか? たまにありますね。
min(max(v, lo), hi)
これがこう書けます。
clamp(v, lo, hi)
#include <algorithm>
ですね。
数学関数
lcm や gcd が #include <numeric>
で使えます。
未定義動作には気をつけましょう。
あと hypot というのがあって、斜辺の長さを求められるのがあります。
hypot(x, y) // sqrt(x*x + y*y)
これの三次元版が追加されます。
hypot(x, y, z) // sqrt(x*x + y*y + z*z)
constexpr if
これはその手の人しか使わなさそう。
optional
これもどうかなぁ。ライブラリ整備勢がうれしくなることがあるのかも?
「この変数は int 型の何かを持っているかもしれないし無を持っているかもしれない」というのを表現できます。
適当な inf で番兵を置かずに、無にしておくことで「inf が小さすぎて WA だった」のような事故を防げそう? いや、場合分けが増えちゃうだけかなぁ。
未定義動作には気をつけましょう。
おわり?
にゃぁ。そのくらいですか? もっとある気もするかも。
この辺を参照するといいかも。