Common sense
-
1e9+7
A large prime, usually used as the modulo.
-
0x3f3f3f3f
usually used as
+inf int
.// binary search int l = 0, r = 0x3f3f3f3f; // dp memset memset(dp, 0x3f, sizeof(dp));
-
leetcode errors
-
Index out of bounds
AddressSanitizer: heap-buffer-overflow AddressSanitizer: stack-buffer-overflow AddressSanitizer: global-buffer-overflow
-
access a deleted array
AddressSanitizer: heap-use-after-free
-
-
c++ solution template
#include <iostream> #include <cstring> #include <cmath> #include <algorithm> #include <climits> #include <stack> #include <queue> #include <vector> #include <set> #include <map> #include <list> #include <cassert> #include <unordered_map> #define DEBUG false #define $(x) {if (DEBUG) {cout << __LINE__ << ": "; {x} cout << endl;}} #define _(x) {cout << #x << " = " << x << " ";} const double E = 1e-8; const double PI = acos(-1); using namespace std; int main() { ios::sync_with_stdio(false); }
-
fast power
// pow(n, p) % M, p >= 0 // int / long long version int power_modulo(int n, int p, int M) { int res = 1; while (p > 0) { if (p % 2 == 1) res = (res * n) % M; p /= 2; n = (n * n) % M; } return res; } // double version double power(double n, long long p) { double res = 1; while (p > 0) { if (p % 2 == 1) ans *= n; p /= 2; n *= n; } return res; }
-
Fibonacci
// dynamic programming, O(N) int fib(int n) { if (n == 0) return 0; else if (n == 1) return 1; int a = 0, b = 1, c; for (int i = 2; i <= n; i++) { c = a + b; a = b; b = c; } return c; } // fast power, O(logN) int fib(int n) { if (n <= 1) return 1; vector<vector<int>> a = {{1, 1}, {1, 0}}; a = matpow(a, n - 2); return a[0][0] + a[0][1]; } vector<vector<int>> matpow(vector<vector<int>> a, int p) { vector<vector<int>> ans = {{1, 0}, {0, 1}}; // I while (p) { if (p % 2) ans = matmul(ans, a); p /= 2; a = matmul(a, a); } return ans; } vector<vector<int>> matmul(vector<vector<int>> a, vector<vector<int>> b) { vector<vector<int>> res(2, vector<int>(2, 0)); res[0][0] = a[0][0] * b[0][0] + a[0][1] * b[1][0]; res[0][1] = a[0][0] * b[0][1] + a[0][1] * b[1][1]; res[1][0] = a[1][0] * b[0][0] + a[1][1] * b[1][0]; res[1][1] = a[1][0] * b[0][1] + a[1][1] * b[1][1]; return res; } // Binet formula, O(1) int fib(int n) { double r = (1 + sqrt(5)) / 2; // 0.618 int ans = (int)round(pow(r, n) / sqrt(5)); // rounded results! return ans; }
-
Bit operator
#define GET_BIT(n, i) (((n) & (1LL << ((i)-1))) >> ((i)-1)) // i start from 1 #define SET_BIT(n, i) ((n) | (1LL << ((i)-1))) #define CLR_BIT(n, i) ((n) & ~(1LL << ((i)-1))) // 2's complement // method1: 全部取反,最后加一 // e.g., -x == (~x) + 1; // method2: 从低位开始找到第一个1为止保持不变(包含第一个1),其余取反。 // e.g., 00111100 --> 11000100 (== 11000011 + 1) // lowbit operator (find the last bit's position) // lowbit(01101000) --> 00001000 auto lowbit = [](int x) { return x & (-x); } // highbit (application of lowbit) // highbit(01101000) --> 01000000 int highbit(int x) { int res = 0; // delayed update, when i == 0, res == last i. for (int i = x; i != 0; i -= lowbit(i)) res = i; return res; } // application: complement without leading 0 // 00000101 --> 00000010 // this equals to masked complement, where we need a highbit mask, and find out a second-highbit mask is also OK (since the highest bit is always 1) // 11111010 & 00000111 == 11111010 & 00000011 == 00000010 int maskedComplement(int x) { int mask = highbit(x) - 1; return (~x) & mask; } // display in binary #include <bitset> void show_binary(unsigned long long x) { printf("%s\n", bitset<64>(x).to_string().c_str()); } // interesting results ('a' | ' ') == 'a'; ('A' | ' ') == 'a'; ('b' & '_') == 'B'; ('B' & '_') == 'B'; ('d' ^ ' ') == 'D'; ('D' ^ ' ') == 'd'; // eliminate last 1 in binary format n = n & (n - 1); // application bool isPowerOfTwo(int n) { if (n <= 0) return false; return (n & (n - 1)) == 0; } int count1(int n) { int ans = 0; while (n) { n &= n - 1; ans++; } return ans; } // 只出现一次的元素 int singleNumber(vector<int>& nums) { int res = 0; for (int n : nums) { res ^= n; } return res; } // simulate a + b int add(int a, int b) { while (b) { unsigned int c = (unsigned int)(a & b) << 1; // to handle negatives a ^= b; b = c; } return a; }
-
implement square root
// binary search // O(logx) float mysqrt(float x, float eps=1e-4) { float l = 0, r = x; while (r - l >= eps) { float m = (l + r) / 2; if (m * m - x > eps) r = m; else l = m; } return l; } // babylonian method (a special case of Newton's method for finding root) // O(logx) float mysqrt(float x, float eps=1e-4) { float r = x, r2; while (true) { r2 = (r + x / r) / 2; // iterate to get better optimzation. if (abs(r2 - r) < eps) break; // the thresold. else r = r2; } return r2; }
-
GCD/LCM
int gcd(int a, int b) { return b == 0 ? a : gcd(b, a % b); } int lcm(int a, int b) { if (gcd(a,b)>0) { return (a / gcd(a, b)) * b; } return 0; }
-
is prime
bool is_prime(int n) { if (n <= 1) return false; if (n == 2) return true; for (int i = 2; i < sqrt(n) + 1; i++) { if (n % i == 0) return false; } return true; } // A prime number greater than 3 can be written in the form 6n - 1 or 6n + 1 // This is of the order O(sqrt(n)) with reduced leading constant bool is_prime(int n) { if (n == 1 || n % 2 == 0) return false; if (n == 2 || n == 3) return true; int t = sqrt(n); int k = t / 6; for (int i = 1; i <= k; i++) { if((n%(6*t - 1)==0) || (n%(6*t + 1)==0)) return false; } return true; } // prime table int is_prime[UP_LIMIT + 1]; for (int i = 1; i <= UP_LIMIT; i++) // init to 1 is_prime[i] = 1; for (int i = 4; i <= UP_LIMIT; i += 2) // even number is not is_prime[i] = 0; for (int k = 3; k*k <= UP_LIMIT; k++) // start from 9, end at sqrt if (is_prime[k]) for(int i = k*k; i <= UP_LIMIT; i += 2*k) // every two is not is_prime[i] = 0;
-
combination & permutation number
//// n choose r mod p // fastpower using ll = long long; ll fastpower(ll a,ll b,ll p) { ll res=1; while(b) { if(b&1) res=res*a%p; a=a*a%p; b>>=1; } return res; } // suitable case: 1 <= r <= n <= 10^3 // 利用递推公式:C(n, r) = C(n-1, r-1) + C(n-r, r) // suitable case: 1 <= r <= n <= 10^6 // 利用乘法逆元,a^{-1} = a^{p-2} (mod p), 通过nCr = n! / r! / (n-r)!计算,通常用打表的形式。 const int maxn = 1e5+5; const int p = 1e9+7; ll fac[maxn], invfac[maxn]; // always use ll, only cast to int for answer. void init(int n) { for (int i = 1; i < n; i++) { fac[i] = (ll) fac[i-1] * i % p; invfac[i] = (ll) invfac[i-1] * fastpower(i, p-2, p) % p; // O(logn) } } ll C(int a, int b) { if (a < b) return 0; return fac[a] * invfac[b] % p * invfac[a-b] % p; } // suitable case: 1 <= r <= n <= 10^18, 1 <= p <= 10^5,p为素数。 // 利用Lucas定理:C(n, r) % p = C(n / p, r / p) * C(n % p, r % p) % p // 10^18输入范围无法打表,故动态计算逆元 ll C(ll a, ll b, ll p) { if (b > a) return 0; ll x = 1, y = 1; for(int i = 1, j = a; i <= b; i++,j--) { x = x * j % p; y = y * i % p; } return x * fastpower(y, p-2, p) % p; } ll lucas(ll a, ll b, ll p) { if (a < p && b < p) return C(a, b, p); else return C(a % p,b % p, p) * lucas(a/p, b/p, p) % p; }
树的拓扑排序数量
class Solution { public: const int M = 1e9 + 7; const static int maxn = 1e5 + 5; using ll = long long; ll fac[maxn], invfac[maxn]; vector<vector<int>> children; ll fastpower(ll a,ll b,ll p) { ll res=1; while(b) { if(b&1) res=res*a%p; a=a*a%p; b>>=1; } return res; } void init(int N) { fac[0] = invfac[0] = 1; for (int i = 1; i < N; i++) { fac[i] = (ll) fac[i-1] * i % M; invfac[i] = (ll) invfac[i-1] * fastpower(i, M-2, M) % M; } } tuple<int,int> solve(int idx) { // leaf if (children[idx].empty()) return {1, 1}; // loop children ll res = 1; int sum_len = 0; for (int i = 0; i < children[idx].size(); i++) { auto [len, perm] = solve(children[idx][i]); sum_len += len; res = res * perm % M * invfac[len] % M; } res = res * fac[sum_len] % M; return {sum_len + 1, res}; } int waysToBuildRooms(vector<int>& prevRoom) { // init (note TLE if init 1e5+5) init(prevRoom.size() + 5); // build tree children.resize(prevRoom.size()); for (int i = 1; i < prevRoom.size(); i++) { children[prevRoom[i]].push_back(i); } // recursive call auto [len, ans] = solve(0); return ans; } };