FastInputを作った
入力が高速になるやつ。実装時間が半分くらいになる
read_syscallを使えばもっと早くなるらしいけど、自分が理解できる範囲にしたかったのと、最初に余分なバッファを取っておかないといけないのが嫌でやめた
使ってみた感想としては「cin の方が打ちやすくてやばい!」「cinのほうが任意の型に対して<<をオーバーロードすれば独自に入力機構作れて最高やん」です
んぐ.iconしばらく使ってみたけど、vscodeならsc.intと打てばsc.nextInt()が補完されるのでそんなに打ちにくくない
もちろん、いいところもあって、
構造化束縛と組み合わせることによって、入力がスマートに実装できる
オフセット便利
code: (cpp)
auto s, t = sc.nextPii(); auto h, w, s = sc.nextAi<3>({ 0, 0, -1 }); // オフセットで1-indexedを0-indexedに 実装
code: (cpp)
struct Scanner {
Scanner() = default;
int nextInt(int offset = 0) const {
char c = skip();
int r = c - '0';
int sgn = 1;
if (c == '-') sgn = -1, r = gc() & 0xf;
else if (c == '+') r = gc() & 0xf;
while (not isspace(c = gc())) r = 10 * r + (c & 0xf);
return sgn * r + offset;
}
char nextChar() const {
return skip();
}
string nextWord() const {
char c = skip();
string r = {c};
while (not isspace(c = gc())) r.push_back(c);
return r;
}
string nextLine() const {
char c;
string r;
while ((c = gc()) != '\n') r.push_back(c);
return r;
}
vi nextVi(int n, int offset=0) const {
vi a(n);
rep(i, n) ai = nextInt(offset); return a;
}
template <size_t N>
array<int, N> nextAi(int offset=0) const {
array<int, N> r;
rep(i, N) ri = nextInt(offset); return r;
}
template <size_t N>
vec<array<int, N>> nextVecAi(int n, int offset=0) const {
vec<array<int, N>> r(n);
rep (i, n) rep(j, N) rij = nextInt(offset); return r;
}
vvi nextVvi(int n, int m, int offset=0) const {
vvi a(n, vi(m));
rep(i, n) rep(j, m) aij = nextInt(offset); return a;
}
set<int> nextSetInt(int n, int offset=0) const {
set<int> r;
rep(n) r.insert(nextInt(offset));
return r;
}
set<char> nextSetChar(int n) const {
set<char> r;
rep(n) r.insert(nextChar());
return r;
}
set<string> nextSetWord(int n) const {
set<string> r;
rep(n) r.insert(nextWord());
return r;
}
pii nextPii() const {
return nextPii(0, 0);
}
pii nextPii(int offset1, int offset2) const {
int a = nextInt(offset1), b = nextInt(offset2);
return make_pair(a, b);
}
vec<pii> nextVecPii(int n) const {
return nextVecPii(n, 0, 0);
}
vec<pii> nextVecPii(int n, int offset1, int offset2) const {
vec<pii> r(n);
rep (i, n) ri = nextPii(offset1, offset2); return r;
}
tuple<int, int, vvi> nextGraph(int offset=-1) const {
int n = nextInt();
int m = nextInt();
vvi g(n);
rep (m) {
int a = nextInt(offset);
int b = nextInt(offset);
}
return make_tuple(n, m, g);
}
tuple<int, int, vvi> nextDirectedGraph(int offset=-1) const {
int n = nextInt();
int m = nextInt();
vvi g(n);
rep (m) {
int a = nextInt(offset);
int b = nextInt(offset);
}
return make_tuple(n, m, g);
}
tuple<int, int, vvi> nextTree(int offset=-1) const {
int n = nextInt();
vvi g(n);
rep (n - 1) {
int a = nextInt(offset);
int b = nextInt(offset);
}
return make_tuple(n, n - 1, g);
}
tuple<int, int, vvi> nextDirectedTree(int offset=-1) const {
int n = nextInt();
vvi g(n);
rep (n - 1) {
int a = nextInt(offset);
int b = nextInt(offset);
}
return make_tuple(n, n - 1, g);
}
private:
char skip() const {
char c;
while (isspace(c = getchar_unlocked())) ;
return c;
}
inline char gc() const { return getchar_unlocked(); }
} sc;