Hello, Codeforces!
In this article, I would like to share with you some general tips'n'tricks you could've used in your cpp sources. Some of them require advanced cpp knowledge, others might not.
bits/stdc++.h
This is a simple enough tip to reduce amount of includes. However, it might not work on your machine: that happens because of bits/stdc++.h
is feature of GCC, not the entire cpp standard. However, there're few ways to workaround it.
Content
Well, before we start to put stdc++.h
to the proper location, there's one thing to determine: content to put in. You either can determine what default headers you might need, or just google "gcc bits/stdc++.h source" and copy/paste it [if you've decided to do so, you might need to remove some gcc-specific headers: just try to compile it and remove one by one non-compiling includes].
Add it to default location
Well, the easiest one is to find one of include paths, like /usr/local/include
(might add to /usr/include
, but it's system directory, do it on your own risk) on Mac, or somewhere else for Windows. All you need to do after this is to create folder bits
and file stdc++.h
inside it.
Add to user-defined header search paths
If you compile/run you code manually, there's the option to add proper location as compiler flag isystem
directly:
$ g++ -std=c++2077 a.cpp -o run_a -isystem /path/to/your/custom/includes
Note that inside folder /path/to/your/custom/includes
must be folder bits
with file stdc++.h
.
Add to you build system
If you're using CMake based build system (what CLion actually does), then you could edit your CMakeLists.txt
directly:
include_subdirectory(/path/to/your/custom/includes)
Prewritten code
According to CodeForces' official rules, you might use some predefined code. But it might be annoying to search over your sources to find the code you need. Well, you could put in a separate file like z.hpp
with all content you might need to use on a contest and simply include it to use all functionality you need without rewriting it.
For example with this file you could write smth like:
#include <bits/stdc++.h>
#include <z.hpp>
using namespace std;
constexpr int mod = 1000 * 1000 * 1000 + 7;
using Mint = Z<mod>;
template <class T>
T bin_pow(T base, int64_t exponent) {
if (exponent == 0) return T(1);
if (exponent % 2 == 1)
return base * bin_pow(base * base, exponent / 2);
return bin_pow(base * base, exponent / 2);
}
int main() {
Mint a, b;
cin >> a >> b;
// note that following addition performed by modulo
cout << a + b << '\n';
// note even pure bin_pow uses modular arithmetics
cout << bin_pow(a, b) << '\n';
}
Don't forget to copy/paste actual source (if you need those) to your file before submitting: there's no z.hpp
accessible by codeforces's compiler. It may be enhanced by custom script doing it instead of you, but there's no such script yet.
stdin
, stdout
, stderr
Your program using at least three streams to communicate with OS: stdin
for input, stdout
for output, and stderr
for errors. Moreover, by default there's sync for cin
and cout
which may slow down you solution on huge inputs because of reading. You could discover more here. If you don't like it appear in main
every time, you could've use the following trick: if you need to run some side effects even before main
starts (like ios::sync_with_stdio(false)
), you could do it while global variables instantiate:
int main() {
// some code
}
// empty namespace to not conflict with any other possible names
namespace {
// global variable assigns to result of the lambda function.
// Since your variable cannot be void, put `int` as result:
auto fast_io = [] {
ios::sync_with_stdio(false);
cin.tie(nullptr);
return 0;
}();
} // namespace
Since any checker/grader reads only stdout
, I strongly recommend using stderr
for debug information (cerr
instead of cout
) — that way once you find out a bug and solved it, you won't need to remove all debugging stuff before submit. However, comparing to remove all code this one could affect performance a bit.
Use some tooling
Since you're writing some code and test it against few testcases it may be annoying to write all of them on your own every time you run the program. To get rid of copy/paste it from a webpage, or trying to copy with spaces from pdf, you could've put it into files at once and run input from file. There's an amazing tool from xalanq. It ignores all your debug output while checking, but still prints it above testing verdicts.
Run debug code only in debug mode
You may need to run some extra code for debugging purposes only. For example, print graph, perform additional checks or compare with the naive solution. It may affect resulting performance and put your from AC zone to TL one. You may delete this code, but if you do so and the solution didn't succeed, you might add some fixes before realizing that you still need that debug code.
There's the straightforward solution: use #ifdef
preprocessor directive:
int main() {
int a, b;
cin >> a >> b;
#ifdef DEBUG
cerr << "a = " << a << " b = " << b << '\n'
#endif // DEBUG
cout << a + b << '\n';
To run this code in debug-mode, you need to pass -DDEBUG
or -D DEBUG
option to your compiler. If you don't know how to do it, or simply don't wanna to do it, codeforces defines ONLINE_JUDGE
for you:
int main() {
int a, b;
cin >> a >> b;
#ifndef ONLINE_JUDGE
cerr << "a = " << a << " b = " << b << '\n'
#endif // ONLINE_JUDGE
cout << a + b << '\n';
Plenty of code just to output two variables, isn't it? Let's solve two problems:
- print all variables given to function (macro)
- write code (block, or just function) that runs in debug mode and event doesn't evaluate arguments in release mode
Printing all variables
Ok, let's provide macro LOG(x, y, z)
that works like cerr << "x = " << x << " y = " << y << " z = " << z << "\n"
, but works with plenty of arguments. Since we can't take x
as string from function argument, let's start from simple scratch:
#define LOG(...) cerr << "[ "#__VA_ARGS__" ] = "; log(__VA_ARGS__);
Where log
function prints all arguments given to it. You could start from scratch like mentioned in my previous article:
template <class ...Args>
auto &log(const Args &...args) {
return ((cerr << " " << as), ...) << '\n';
}
Let's put it all together:
template <class ...Args>
auto &log(const Args &...args) {
return ((cerr << " " << as), ...) << '\n';
}
#define LOG(...) cerr << "[ "#__VA_ARGS__" ] = "; log(__VA_ARGS__);
int main() {
int a, b;
cin >> a >> b;
LOG(a, b, a + b);
// prints: [ a, b, a + b ] = 2 2 4
cout << a + b << '\n';
}
Well, there's plenty things you could've improved, like mentioned in this discussion. However, it still doesn't work fine for things with comma in subexpressions like:
LOG(a, b, some_func(a, b))
Running code in debug mode only
How to run code in debug and even don't evaluate arguments in release mode? Well, here's trick you might seen here involving if
:
#ifndef DEBUG
#define CERR if (false) cerr
#endif
// somewhere in code
CERR << "a = " << a << '\n';
// expands to
if (false) cerr << << "a = " << a << '\n';
But there's bug here:
if (a == 0)
CERR << "b=" << b << '\n';
else {
CERR << "c=" << c << '\n';
// dance like no one's watching
// with a != 0
}
// expands to
if (a == 0)
if (false)
cerr << "b=" << b << '\n';
else {
if (false)
cerr << "c=" << c << '\n';
// a is still zero here :(
}
Well, there's alternative with while (false)
which doesn't have such bugs. But what to do instead of while (false)
to run any code? We may try to put nothing [don't know if there's bug], but I'd prefer one time running for
. Let's put it all together:
template <class ...Args>
auto &log(const Args &...args)
{ return ((cerr << " " << as), ...) << '\n'; }
#ifdef DEBUG
# define LOG(...) cerr << "[ "#__VA_ARGS__" ] = "; log(__VA_ARGS__)
# define RUN for (bool _flag = true; _flag; _flag = !_flag)
#else // DEBUG
# define LOG(...) while (false) cerr
# define RUN while (false)
#endif // DEBUG
int main() {
int n, m;
cin >> n >> m;
LOG(n, m);
vector<vector<int>> g(n);
for (int e = 0; e < m; ++e) {
int u, v;
cin >> u >> v;
g[--u].push_back(--v);
g[v].push_back(u);
}
RUN {
for (int u = 0; u < n; ++i) {
cerr << u << ":";
for (int v : g[u])
cerr << " " << v;
cerr << "\n";
}
}
}
auto
There's the keyword to replace all boring types you don't need to write explicitly:
for (auto it = xs.begin(); it != xs.end(); ++it)
for (auto foo : foos)
But there's a hidden problem: unnecessary copying:
for (auto row : table) {
// here row has type vector<Cell>
// which copied from table even if you don't modify it
}
To avoid it, you could've used:
for (auto &row : table)
But, it might be a temporary object, what kind of annoying. To resolve it, you could've used universal reference everywhere:
// works just fine: no copies,
// reference if regular object
// value if temporary one
for (auto &&row : table)
Ok, where to use it?
Predicates
It you're using lambdas, you might not know about generic lambdas, let me show the use case:
vector<pair<int, int>> some_events = ...;
sort(some_events.begin(), some_events.end(), [&](auto &&lhs, auto &&rhs) {
// compare two pair<int, int> here
});
You might notice that you often write code like return foo(lhs) < foo(rhs);
. Here's way to get rid of it:
#define BY_FUNC(func) [&](auto &&lhs, auto &&rhs) { \
return func(lhs) < func(rhs); \
}
sort(some_events.begin(), some_events.end(), BY_FUNC(some_func));
Much better (you could come up with a shorter name for macro), but if you want to compare only .second
, it's not suitable :(. However, we could generate all necessary code on our own (thanks to viskonsin for pitching me this idea):
#define UNARY(...) [&](auto &&lhs, auto &&rhs) { \
auto predicate = [&](auto &&x) { \
return __VA_ARGS__; \
}; \
return predicate(lhs) < predicate(rhs); \
}
sort(pairs.begin(), pairs.end(), UNARY(x.second));
// expands to:
sort(pairs.begin(), pairs.end(), [&](auto &&lhs, auto &&rhs) {
auto predicate = [&](auto &&x) {
return x.second;
};
return predicate(lhs) < predicate(rhs);
});
// such a plenty of code out of one short macro!
dbg
macro
Thanks to ramchandra for his amazing dbg
macro, really nice job. However, there's dbg!
macro in Rust. Let's develop same behavior: after expression is surrounded with dbg(expr)
work as simple expr
in release mode and additionally prints it in debug mode. Well, implementation for release mode is pretty straightforward:
#define dbg(...) __VA_ARGS__
And what with debug one? I'd like to work with any kind of references here, to write smth like:
auto it = dbg(order).find(dbg(x + 1));
Okay, it must be a result of expression with necessary debug output. Let's use simple lambda on fly:
int recursion_depth = 0;
#define dbg(x) [&]() -> auto&& { \
++recursion_depth; \
auto &&value = x; \
cerr << string(recursion_depth, '\t') \
<< #x" = " << value << endl; \
--recursion_depth; \
return value; \
}()
What's next?
There're amazing articles from Golovanov399 here, and from HosseinYousefi here — check them, they cover a lot of things (like all(xs)
macro) I omitted. There's also another my article about reading and declaring variables at once. After all, more will come, stay tuned!
I would like to thank:
- viskonsin for help with editing this article
- Golovanov399, HosseinYousefi and ramchandra for their amazing articles
- xalanq for wonderful cf-tool
- You for reading this article!
See ya!