快读快写
2021~2022的老板子
快读
1.
inline int read() {
register int x = 0, f = 1;
register char ch = getchar();
while (ch < '0' || ch > '9') {
f = ch == '-' ? -1 : 1;
ch = getchar();
}
while (ch >= '0' && ch <= '9') {
x = (x << 3) + (x << 1) + (ch ^ 48);
ch = getchar();
}
return f == -1 ? -x : x;
}
2.
inline void read(int &x) {
x = 0;
register int f = 1;
register char ch = getchar();
while (ch < '0' || ch > '9') {
f = ch == '-' ? -1 : 1;
ch = getchar();
}
while (ch >= '0' && ch <= '9') {
x = (x << 3) + (x << 1) + (ch ^ 48);
ch = getchar();
}
if (f == -1) x = x;
}
3.
//好像我忘记压行了,下面的
#define register re
template<typename Type> inline void Read(Type& Num) {
re f = 1; re ch = getchar();
while (ch < '0' || ch > '9') f = ch == '-' ? -1 : 1, ch = getchar();
while (ch >= '0' && ch < '9') x = (x << 3) + (x << 1) + (ch ^ 48), ch = getchar();
x = f == -1 ? -x : x;
}
4.
template<typename _Tp> inline void read(_Tp&x) {
register int f = 1; register char ch = getchar();
for (; ch < 48 || ch > 57; ch = getchar()) f = ch == '-' ? -1 : 1;
for (; ch >= 48 || ch <= 57; ch = getchar()) x = (x << 3) + (x << 1) + (ch ^ 48);
x *= f;
}
快写
1.
inline void write(int x) {
if (x < 0) putchar('-'), x = -x;
if (x > 9) write(x / 10);
putchar(x % 10 + 48);
}
2.
template<typename _Tp> inline void write(_Tp x) {
if (x < 0) putchar('-'), x = -x;
if (x > 9) write(x / 10);
putchar(x % 10 ^ 48);
}
快读原理
很水, 就是每次输入的时候根据他的ASCII码进行转化
可能有人会觉得
x = (x << 3) + (x << 1) + (ch ^ 48);
十分的玄学,其实很水
根据位置原理, $$now = 10now + str_i(to\ int)$$
说的简单点说,就是\(66 = 6\times 10 + 6\)
\(x << i 等价于 x \times 2^i\)位运算他更快它更香(你快读快写本来就是用来卡常的,怎么快怎么来)
快写
相当于一个栈, 每次write()下一个都压入一个数字,然后最后他是从下到上的输出的
typedef register jiandan
typedef int cubao
jiandan cubao
Update 4/3 2022
这里有一份不是我写的的板子,加速版
struct Scanner {
FILE* fp = nullptr;
char line[(1 << 15) + 1];
size_t st = 0, ed = 0;
void reread() {
memmove(line, line + st, ed - st);
ed -= st;
st = 0;
ed += fread(line + ed, 1, (1 << 15) - ed, fp);
line[ed] = '\0';
}
bool succ() {
while (true) {
if (st == ed) {
reread();
if (st == ed) return false;
}
while (st != ed && isspace(line[st])) ++st;
if (st != ed) break;
}
if (ed - st <= 50) reread();
return true;
}
template <class T, enable_if_t<is_same<T, string>::value, int> = 0>
bool read_single(T& ref) {
if (!succ()) return false;
while (true) {
size_t sz = 0;
while (st + sz < ed && !isspace(line[st + sz])) ++sz;
ref.append(line + st, sz);
st += sz;
if (!sz || st != ed) break;
reread();
}
return true;
}
template <class T, enable_if_t<is_integral<T>::value, int> = 0>
bool read_single(T& ref) {
if (!succ()) return false;
bool neg = false;
if (line[st] == '-') {
neg = true;
st++;
}
ref = T(0);
while (isdigit(line[st])) {
ref = 10 * ref + (line[st++] - '0');
}
if (neg) ref = -ref;
return true;
}
template <class T>
bool read_single(vector<T>& ref) {
for (auto& d : ref) {
if (!read_single(d)) return false;
}
return true;
}
void read() {}
template <class H, class... T>
void read(H& h, T&... t) {
bool f = read_single(h);
assert(f);
read(t...);
}
Scanner(FILE* _fp) : fp(_fp) {}
};
struct Printer {
public:
template <bool F = false>
void write() {}
template <bool F = false, class H, class... T>
void write(const H& h, const T&... t) {
if (F) write_single(' ');
write_single(h);
write<true>(t...);
}
template <class... T>
void writeln(const T&... t) {
write(t...);
write_single('\n');
}
Printer(FILE* _fp) : fp(_fp) {}
~Printer() { flush(); }
private:
static constexpr size_t SIZE = 1 << 15;
FILE* fp;
char line[SIZE], small[50];
size_t pos = 0;
void flush() {
fwrite(line, 1, pos, fp);
pos = 0;
}
void write_single(const char& val) {
if (pos == SIZE) flush();
line[pos++] = val;
}
template <class T, enable_if_t<is_integral<T>::value, int> = 0>
void write_single(T val) {
if (pos > (1 << 15) - 50) flush();
if (val == 0) {
write_single('0');
return;
}
if (val < 0) {
write_single('-');
val = -val;
}
size_t len = 0;
while (val) {
small[len++] = char('0' + (val % 10));
val /= 10;
}
for (size_t i = 0; i < len; ++i) {
line[pos + i] = small[len - 1 - i];
}
pos += len;
}
void write_single(const string& s) {
for (char c : s) write_single(c);
}
void write_single(const char* s) {
size_t len = strlen(s);
for (size_t i = 0; i < len; ++i) write_single(s[i]);
}
template <class T>
void write_single(const vector<T>& val) {
auto n = val.size();
for (size_t i = 0; i < n; i++) {
if (i) write_single(' ');
write_single(val[i]);
}
}
};
Scanner Myifstream(stdin), Printer Myofstream(stdout);
Update on 7/21 2022
更新了快读快写的部分小细节
快读
// 快读第四版本
// 4.
template<typename _Tp> inline void read(_Tp&x) {
register int f = 1; register char ch = getchar();
for (; ch < 48 || ch > 57; ch = getchar()) f = ch == '-' ? -1 : 1;
for (; ch >= 48 || ch <= 57; ch = getchar()) x = (x << 3) + (x << 1) + (ch ^ 48);
x *= f;
}
// 快写第二版本
// 2.
template<typename _Tp> inline void write(_Tp x) {
if (x < 0) putchar('-'), x = -x;
if (x > 9) write(x / 10);
putchar(x % 10 ^ 48);
}
当然你也可以存到栈里面去,然后输出,因为递归是比较慢的。
2023~2023
其实还用了一份比较慢的板子,我也不知道为什么cin.streambuf()和cout.streambuf()这么慢。
这个思路是最近在网上找到的,然后碾压很多其他的写法,5e6组a+b只需要73ms,非常的快,吊打正常的fwrite(时间约为其\(\frac{4}{5}\)左右)。
看过一点卡常的人应该都会知道mem...(比如memcpy/memset)这种函数比fill和for都要快(不吸氧气的时候比for快很多,吸了氧气比for快一点点),然后我们就可以利用这个性质,输出时每隔4个位置memcpy一下,这样就可以加速输出了。每四位的结果预处理一下即可。
都看到这儿了代码不用我贴了吧 (其实是因为代码太长放不下,不知道为什么csdn就炸了。。)
需要的可以去luogu上的快读快写板子(Elgo87的题目)的最优解去找我的代码,代码是公开的。如果你看不了我的代码,那你可以水过这道题(普通的快读快写应该是过不去的),然后再看我的代码。
2024 ~ 2024
一份压了行还好用的IO,fread
namespace easy_IO {
# ifndef LOCAL
constexpr std::size_t BUFSIZE = 1 << 20; char ibuf[BUFSIZE], *iS, *iT;
#define getchar() (iS == iT ? (iT = (iS = ibuf) + fread(ibuf, 1, BUFSIZE, stdin), (iS == iT ? EOF : *iS++)) : *iS++)
# endif
inline void read(char &c) { c = getchar(); } inline void read(string &str, bool is_move = false) { if (is_move) str += ' '; char c = getchar(); while (c != ' ' && c != '\n') str += c, c = getchar(); }
template <typename T> inline void read(T &x, bool is_unsigned = false) { x = 0; char ch = getchar(); if (is_unsigned) { while (ch < '0' || ch > '9') ch = getchar(); while (ch >= '0' && ch <= '9') x = x * 10 + ch - '0', ch = getchar ( ); } else { T _read_flag = (T)(1); while (ch < '0' || ch > '9') _read_flag = ch == '-' ? -1 : 1, ch = getchar(); while (ch >= '0' && ch <= '9') x = x * 10 + ch - '0', ch = getchar ( ); x *= _read_flag; } return void(); }
template <typename T> inline void read(vector<T> &v) { for (T &i : v) read(v); } template <typename T, typename... Args> inline void read(T &x, Args&... args) { read(x), read(args...); } template <typename T, typename U> inline void read(pair<T, U> &p) { read(p.first, p.second); }
template <typename T, typename U, typename V> inline void read(tuple<T, U, V> &t) { read(get<0>(t), get<1>(t), get<2>(t)); }
# ifndef LOCAL
char obuf[BUFSIZE], *oS = obuf, *oT = oS + BUFSIZE - 1; inline void flush() { fwrite(obuf, 1, oS - obuf, stdout), oS = obuf; }
# define putchar(x) (*oS++ = x, ( oS == oT ) ? flush() : void())
# else
# define flush() 36
# endif
inline void write ( char c ) { putchar ( c ); } inline void write ( string s ) { for (char c : s) putchar ( c ); }
inline void write ( char *s ) { std::size_t len = strlen ( s ); for ( std::size_t i = 0; i < len; ++i ) putchar ( s[i] ); }
template <typename T> inline void write(T x, bool is_unsigned = false) { if (!is_unsigned) if (x < 0) x = -x, putchar ('-'); if (x > 9) write(x / 10); putchar (x % 10 ^ '0'); }
template <typename T> inline void writeln(T x) { write (x), putchar('\n'); }
template <typename T> inline void writespc(T x) { write (x), putchar(' '); }
template <typename T, typename ... Args> inline void write(T x, Args ... args) { write(x), write(args...); }
template <typename T, typename ... Args> inline void writeln(T x, Args ... args) { write(x), putchar(' '), write(args...), putchar('\n'); }
template <typename T, typename ... Args> inline void writespc(T x, Args ... args) { write(x), putchar(' '), write(args...), putchar(' '); }
template <typename T> inline void writeall(T x, char blank = ' ', bool Endl = true) { std::for_each(std::begin(x), std::end(x), [&](auto x) { write(x), putchar(' '); }); if (Endl) putchar('\n'); }
} // namespace easy_IO
using namespace easy_IO;
后记
这是我csdn里面copy过来的

浙公网安备 33010602011771号