module main; import std; // https://klee.hatenablog.jp/entry/2020/06/18/210754 より // 最長回文半径の配列を計算する // padding: 偶数長の回文を調べるための詰め物 long[] manacher(string padding = "#")(string _s) { auto s = padding ~ _s.map!(a => only(a)).joiner(padding).array.to!string ~ padding; long n = s.length; auto rad = new long[](n); long c = 0, r = 0; while (c < n) { // cを中心に同じ文字がどこまで連続するか while (0 <= c - r && c + r < n && s[c - r] == s[c + r]) r++; rad[c] = r; // 回文の長さに応じて利用可能な範囲を確認しつつメモ long k = 1; while (0 <= c - k && k + rad[c - k] < r) { rad[c + k] = rad[c - k]; k++; } //すでに計算が終わった分だけ中心と探索半径をずらす c += k; r -= k; } // paddingの分の補正 foreach (i, ref v; rad) { if (i % 2 == 0) v = (v - 1) / 2; else v /= 2; } return rad; } void main() { // 入力 long L = readln.chomp.to!long; // 答えの計算 auto res = manacher("ab".repeat(L / 2).joiner("").array.to!string ~ "a").filter!(a => a >= 2); // 答えの出力 writeln(res.sum - res.walkLength); }