From 5a7162bcda6856e7506827a09fcf3bccf7decf7b Mon Sep 17 00:00:00 2001 From: un-lock-able Date: Thu, 21 Aug 2025 23:24:24 +0800 Subject: [PATCH] add cheatsheet --- 0-0-test.cpp | 6 + leetcodecheatsheet/cpp_reference.typ | 1102 +++++++++++++++++++++++++ leetcodecheatsheet/img/三角形剖分.png | Bin 0 -> 44898 bytes 3 files changed, 1108 insertions(+) create mode 100644 0-0-test.cpp create mode 100644 leetcodecheatsheet/cpp_reference.typ create mode 100644 leetcodecheatsheet/img/三角形剖分.png diff --git a/0-0-test.cpp b/0-0-test.cpp new file mode 100644 index 0000000..df5b480 --- /dev/null +++ b/0-0-test.cpp @@ -0,0 +1,6 @@ +#include + +int main() { + std::cout << "Hello world" << std::endl; + return 0; +} \ No newline at end of file diff --git a/leetcodecheatsheet/cpp_reference.typ b/leetcodecheatsheet/cpp_reference.typ new file mode 100644 index 0000000..82e98fd --- /dev/null +++ b/leetcodecheatsheet/cpp_reference.typ @@ -0,0 +1,1102 @@ +// C Standard Library Cheatsheet Template +// A clean, two-column layout for quick reference during coding interviews. +// Created with Typst. + +// ================= DOCUMENT SETUP ================= +#set document(title: "C Standard Library Reference", author: "David Gao") + +#let base-text-size = 9pt + +#set text(font: ("Arial", "DengXian"), size: base-text-size, lang: "zh") +#show raw: set text( + font: ( + "Cascadia Code", + "SimHei", + ), +) + +#set page(paper: "a4", margin: (top: 0.75in, bottom: 0.75in, left: 0.5in, right: 0.5in)) + +// Define colors for styling to make sections stand out. +#let primary_color = navy +#let secondary_color = luma(230) + +// ================= CUSTOM SHOW RULE (The Cheatsheet Engine) ================= +#let entry(signature, description, code_lang: "cpp") = { + grid.cell[ + #rect(width: 100%, inset: (x: 4pt, y: 3pt), fill: luma(240), radius: 2pt, [#raw(signature, lang: code_lang)]) + ] + grid.cell[ + #description + ] +} + +// This function formats a larger code snippet for algorithms/data structures. +#let code_snippet(body, title: none) = { + // This `if` statement checks if a title was passed. + // If `title` is anything other than `none`, this block is rendered. + if title != none { + pad(bottom: 4pt, text(weight: "bold", title)) + } + + // The main block for the code is always rendered. + block( + width: 100%, + inset: 8pt, + fill: luma(240), + radius: 3pt, + body, + ) + v(1em) +} + +// ================= HEADER FUNCTION ================= +#let section_header(title) = { + // v(0.5em) + block(width: 100%, fill: primary_color, inset: 6pt, radius: 3pt, text(white, weight: "bold", title)) + v(0.5em) +} + +// ================= SUBSECTION HEADER FUNCTION ================= +#let subsection_header(title) = { + // v(1.2em) // A bit of space above the subsection title. + // Make text bold, slightly larger, and use the primary color. + text(weight: "bold", title) + // Add a subtle line underneath to separate it from the content. + line(length: 100%, stroke: 0.5pt + primary_color) + v(0.6em) // Space after the subsection header. +} + +#show heading.where(level: 1): it => section_header(it.body) +#show heading.where(level: 2): it => subsection_header(it.body) + +// ================= CHEATSHEET CONTENT ================= + +// Main Title +#align(center)[ + #text(size: 20pt, weight: "bold", "C Standard Library Reference") + #line(length: 100%, stroke: 1pt) + #v(1em) +] + +#section_header([`stdio.h`]) + +#grid( + columns: (auto, 1fr), + column-gutter: 8pt, + row-gutter: 6pt, +)[ + #entry( + "int printf(const char* format, ...);", + [Prints formatted output to `stdout`. Common specifiers: `%d` (int), `%f` (float/double), `%c` (char), `%s` (string), `%p` (pointer).], + ) + #entry( + "int sprintf(char* str, const char* format, ...);", + [Prints formatted output to a string `str`.], + ) + #entry( + "int scanf(const char* format, ...);", + [Reads formatted input from `stdin`.], + ) + #entry( + "int getchar(void);", + [Reads the next character from `stdin`.], + ) + #entry( + "int putchar(int ch);", + [Writes a character `ch` to `stdout`.], + ) +] + +#section_header([`string.h`]) + +#grid( + columns: (auto, 1fr), + column-gutter: 8pt, + row-gutter: 6pt, +)[ + #entry( + "void *memset(void *str, int c, size_t n);", + [`n` is the number of bytes needed to be set. Can be obtained by `sizeof(array)`, where `array` is of type `T[]`.], + ) + #entry( + "void *memcpy(void *dst, const void *src, size_t n);", + [ + Copy `n` bytes of data starting from `src` into `dst`. 需要确保`src`和`dst`空间不重叠。 + ], + ) + #entry( + "int strcmp (const char * str1, const char * str2);", + [返回`str1`与`str2`的字典序,`str1`在前则$<0$,`str1`在后则$>0$。返回0则相等。], + ) + #entry( + "size_t strlen(const char *str);", + [返回字符串长度], + ) + #entry( + "char *strcpy(char *__restrict__ _Dest, const char *__restrict__ _Source);", + [将`src`内的字符串复制进`dest`], + ) + #entry( + "char *strcat(char *dest, const char *src);", + [把`src`所指向的字符串追加到`dest`所指向的字符串的结尾], + ) + #entry( + "char *strchr(const char *str, int c);", + [在参数`str`所指向的字符串中搜索第一次出现字符 `c`(一个无符号字符)的位置。], + ) + #entry( + "char *strpbrk(const char *str1, const char *str2);", + [检索字符串`str1`中第一个匹配字符串`str2`中某个字符的字符,不包含空结束字符。也就是说,依次检验字符串`str1`中的字符,当被检验字符在字符串`str2`中也包含时,则停止检验,并返回该字符位置。], + ) + #entry( + "char *strstr(const char *haystack, const char *needle);", + [在字符串`haystack`中查找第一次出现字符串`needle`(不包含空结束字符)的位置。], + ) + #entry( + "char *strtok(char *str, const char *delim);", + [ + 分解字符串 str 为一组字符串,delim 为分隔符。 + ```c + char *token = strtok(str, s); + /* 继续获取其他的子字符串 */ + while(token != NULL) { + printf("%s\n", token); + token = strtok(NULL, s); + } + ``` + ], + ) +] + + +// --- stdlib.h Section --- +#section_header([`stdlib.h`]) + +#grid( + columns: (auto, 1fr), + column-gutter: 8pt, + row-gutter: 6pt, +)[ + #entry( + "void* malloc(size_t size);", + "Allocates `size` bytes of uninitialized memory. Returns a void pointer to the allocated space.", + ) + #entry( + "void* calloc(size_t nmemb, size_t size);", + "Allocates memory for an array of `nmemb` elements of `size` bytes each and initializes all bits to zero.", + ) + #entry( + "void* realloc(void* ptr, size_t size);", + "Resizes the memory block pointed to by `ptr` to `size` bytes. The content will be unchanged up to the minimum of the old and new sizes.", + ) + #entry( + "void free(void* ptr);", + "Deallocates a block of memory previously allocated by `malloc`, `calloc`, or `realloc`.", + ) + #entry("int atoi(const char* str);", "Converts the initial portion of the string `str` to an `int`.") + #entry( + "long int strtol(const char* str, char** endptr, int base);", + "Converts string `str` to a `long int`. `endptr` can be used to see where conversion stopped. `base` is the number base (e.g., 10).", + ) + #entry( + "void qsort(void* base, size_t nmemb, size_t size, int (*compar)(const void*, const void*));", + "Sorts an array. `compar` is a pointer to a function that compares two elements.", + ) + #entry("int rand(void);", "Returns a pseudo-random integer between 0 and `RAND_MAX`.") + #entry("void srand(unsigned int seed);", "Seeds the pseudo-random number generator used by `rand()`.") + #entry("void exit(int status);", "Causes normal program termination. `EXIT_SUCCESS` or `EXIT_FAILURE`.") +] + +#v(1.5em) + +// --- string.h Section --- += `string.h` — String Manipulation + +#grid( + columns: (auto, 1fr), + column-gutter: 8pt, + row-gutter: 6pt, +)[ + #entry( + "size_t strlen(const char* s);", + "Calculates the length of string `s`, excluding the terminating null byte (`'\\0'`).", + ) + #entry( + "char* strcpy(char* dest, const char* src);", + "Copies the string `src` to `dest`. *Unsafe*, does not check buffer size.", + ) + #entry( + "char* strncpy(char* dest, const char* src, size_t n);", + "Copies up to `n` characters from `src` to `dest`. May not be null-terminated if `src` is too long.", + ) + #entry( + "int strcmp(const char* s1, const char* s2);", + "Compares two strings. Returns < 0 if s1 < s2, 0 if s1 == s2, > 0 if s1 > s2.", + ) + #entry( + "char* strchr(const char* s, int c);", + "Returns a pointer to the first occurrence of character `c` in string `s`, or `NULL` if not found.", + ) + #entry( + "char* strstr(const char* haystack, const char* needle);", + "Finds the first occurrence of the substring `needle` in the string `haystack`.", + ) + #entry( + "void* memset(void* s, int c, size_t n);", + "Fills the first `n` bytes of the memory area pointed to by `s` with the constant byte `c`.", + ) + #entry( + "void* memcpy(void* dest, const void* src, size_t n);", + "Copies `n` bytes from memory area `src` to memory area `dest`.", + ) +] + += 常用技巧 + +== 防止栈溢出 +```c +#pragma comment(linker, "/STACK:1024000000,1024000000") +``` + +== C++常用头文件 +```cpp +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +``` + += Common Algorithms & Data Structures + +== 字符串匹配 + +=== KMP算法:$O(n)$ + +#code_snippet[ + ```cpp + int next[MAXN]; + int KMP(string txt, string pattern) { + int i = next[0] = -1 + int j = 0; + int n = text.size(); + int m = pattern.size(); + + // 生成next表 + while (j < m) { + if (i == -1 || pattern[j] == pattern[i]) { + i++; + j++; + next[j] = i; + } else { + i = next[i]; + } + } + + // KMP + i = j = 0; + while (i < m && j < n) { + if (i == -1 || text[j] == pattern[i]) { + i++; + j++; + } else { + i = next[i]; + } + + if (i == m) { + // 成功匹配,第一个字符在text的index为i - j + 1 + // 完美匹配,当作失配处理 + // i = next[i]; + } + } + } + ```] + +== 日期处理 + +#code_snippet[```cpp +struct Date{ + int year, month, day; + Date(int y, int m, int d): year(y), month(m), day(d) {} + int week(){ // 今天是星期几? 基姆拉尔森公式 + int y = year, m = month, d = day; + if( m == 1 || m == 2 ) { + m += 12; + y--; + }; + int w = (d + 2*m + 3*(m+1)/5 + y + y/4 - y/100 + y/400) % 7; + return ++w; // w:0:星期一...依此类推 + } + int MONTH[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; + int kthDay(){ // 给定一个日期,输出这个日期是该年的第几天 + if(year % 4 == 0 && (year % 100 || year % 400 == 0)) + MONTH[2] = 29; + int days = 0; + for (int i = 1; i < month; i++) days += MONTH[i]; + return days += day; + } +}; +```] + + +== 排序 + +=== 快速排序:$Theta (n log n) + O(1)$ + +#code_snippet[```cpp +void quicksort(vector &a, int le, int ri) { + // 排序[le, ri) + int i = le, j = ri - 1; + int pivot = a[(rand()%(ri-le))+le]; + while (i <= j) { + while (a[i] < pivot) i++; + while (a[j] > pivot) j--; + if (i <= j) swap(&a[i++], &a[j--]); // 先swap,之后执行自增 + } + + if (le < j) quicksort(a, le, j + 1); + if (i < ri - 1) quicksort(a, i, ri); +} +```] + +=== 归并排序/求逆序对:$O(n log n) + O(n)$ + +#code_snippet[```cpp +long long mergesort(vector& a, long long le, long long ri){ + long long ans = 0; + if(le >= ri - 1) return 0; + long long mid = (le + ri) >> 1; + ans += mergesort(a, le, mid); + ans += mergesort(a, mid, ri); + + vector b; //辅助数组 + long long p = le, q = mid; + long long count = 0; + while(p < mid && q < ri){ + if(a[p] <= a[q]) b.push_back(a[p++]); + else{ + b.push_back(a[q++]); + count += (mid - p); // 求逆序 + } + } + while(p < mid) b.push_back(a[p++]); + while(q < ri) b.push_back(a[q++]); + for(long long i = le; i < ri; ++i) + a[i] = b[i-le]; + + ans += count; + //ans += min(count, (mid - le)*(ri - mid) - count); //求二叉树最小逆序 + return ans; +} +```] + +== 二分查找:$O(log n)$ + +#code_snippet[```cpp +int binarySearch(vector &a, int e){ // 保证输入有序; lower_bound形式 + int le = 0, ri = a.size(); + while(ri - le > 1){ // [le, ri)夹逼 + int mid = (le + ri) >> 1; + if(a[mid] <= e) + le = mid; // le处元素总是<= + else + ri = mid; // ri处元素总是> + } + return le; // 返回下标 +} +```] + +== 贪心问题 + +=== 区间选点 + +数轴上$n$个闭区间,尽可能选择少的点,使得每个区间内至少有一个点被选到。 + +解法:将区间结束点从小到大排列;选第一个结束点作为我们选择的第一个点,删去所有已经被选了点的区间;不停地选择剩余区间中结束点最靠前的点,直到所有区间都有至少一个点。 + +=== 区间覆盖 + +数轴上有数个区间$[a, b]$。给定一个线段$[s, t]$,使用最少数量的区间将线段完全覆盖。 + +解法:在预处理:将各个区间按$a$的大小排序。首先确认最小的开头在$s$前,否则直接无解。之后使用贪心。对于所有$a < s$的区间,找$b$最大的(这样能覆盖更多)。之后将$s$移动到$b$,接着寻找新的最长的,直到全部覆盖。 + +== DP + +=== 普通背包问题:$O(n V) + O(V)$ + +第`i`个物品的体积为`w[i]`,价值为`v[i]`,`d[i][j]`代表从开头到第`i`个物品(包含)在`j`体积内能达到的最大价值。由于`d[i + 1]`只依赖于`d[i]`,数组只需要一维。需要从`j`较大的往下更新,防止更新大`j`时用到的小`j`的价值是已经是加入了本物品的价值。 + +#code_snippet(```cpp +int dp[MAXN]; +int backpack(vector w, vector v, int n, int V) { // n为物品数,V为总容量 + for (int i = 0; i < n; i++) { + for (int j = V; j >= w[i]; j--) { + dp[j] = max(dp[j], dp[j - w[i]] + v[i]); + } + } +} +```) + +=== 完美背包问题:$O(n V) + O(V)$ + +与普通背包的区别是每个物品都有无限个。只要正向更新,刚好满足要求(考虑大体积时可以用之前已经加了这个物品的接着加入)。 + +#code_snippet(```cpp +int dp[MAXN]; +int backpack(vector w, vector v, int n, int V) { // n为物品数,V为总容量 + for (int i = 0; i < n; i++) { + for (int j = w[i]; j <= V; j++) { + dp[j] = max(dp[j], dp[j - w[i]] + v[i]); + } + } +} +```) + +=== 多重背包:$O(V sum(log_2(k_i)))$ + +对于第`i`种物品,体积`w[i]`,价值`v[i]`,数量`k[i]`。对数量进行二进制拆分:$k = 1 + 2 + 4 + dots + 2^p + (k - (2^(p + 1) - 1))$。这些数量的物品各自算作一个新物品,继续做01背包。 + +拆分代码: + +#code_snippet(```cpp +int __v[MAXN], __w[MAXN], cnt = 0; // 拆分后物品总数 +for(int i = 0; i < n; ++i){ // 分组 + int v, w, k; + scanf("%d%d%d", &w, &v, &k); + int c = 1; + while(k - c > 0){ + k -= c; + __w[cnt] = c*w; + __v[cnt++] = c*v; + c *= 1; + } + __w[cnt] = k*w; + __v[cnt++] = k*v; +} +```) + +=== 最优多边形剖分:$O(n^3)$ + +多边形中任意两点$i, j$间的弦有某个权值$w(i, j)$。求将多边形分割成数个三角形所需的最低权值。我们可以用$d(i, j)$表示子多边形$i, i + 1, dots, j - 1, j$的最优解(这个多边形是我们通过选择$i j$这条弦切割出来的)。那么 +$ d(i, j) = max_(i < k < j){d(i, k) + d(k, j) + w(i, k) + w(k, j)} $ + +#figure( + image( + "./img/三角形剖分.png", + width: 30%, + ), +) #label("fig: 三角剖分") + +=== 数位DP + +给出某个范围$[a, b]$求在这个范围中满足一定要求的数有多少个(通常与数大小等没有关系,与数的数位(digit)有关)。例如,给定$[a,b]$,求范围内每个数位出现次数。 + +解法:首先需要几个数组:$text("ten")(i)$为$10^i$,$f(i)$为$[0, 10^i - 1]$范围内任意数位出现的次数。这是我们DP算法的核心。核心状态转移: +$ f(i) = f(i - 1) times 10 + text("ten")(i) $ + +即对于所有小于等于$i$位的数,我们$i - 1$中重复了10次,最高位中我们关心的这个数(不论是0-9中的哪个)作为最高位的数都有$10^i$个。 + +#code_snippet(```cpp +#include +using namespace std; +long long a,b; +long long ten[20],f[20]; +long long cnta[20],cntb[20]; +void solve(long long x,long long *cnt){ + long long num[20]={0}; + int len=0; + while(x){ // 对x进行数位分解 + num[++len]=x%10; + x=x/10; + } + // 最低位在num[1],最高位在num[len] + + // 一下以543这个数为例。num = {0, 3, 4, 5} + // 从最高位开始往下。以5为例 + for(int i=len; i>=1; i--){ + // 处理0 - 499的计数,以及5作为首位的计数 + for(int j=0; j<=9; j++) + // 每个数位在0-499的十位和个位均匀出现。 + cnt[j] += f[i-1] * num[i]; + for(int j=0; j=1; j--){ + num2 = num2 * 10 + num[j]; + } + // 5作为百位出现了43 + 1次 + cnt[num[i]]+=num2+1; + // 0作为百位时不会被写出来。 + cnt[0]-= ten[i-1]; + } +} +int main() +{ + scanf("%lld %lld",&a,&b); // 区间范围 + ten[0]=1; + for(int i=1;i<=15;i++) + { + f[i]=f[i-1]*10+ten[i-1]; + ten[i]=10*ten[i-1]; + } + solve(a-1,cnta); // [1, a-1]总计数 + solve(b,cntb); // [a, b]总计数 + for(int i=0;i<=9;i++) + printf("%lld ",cntb[i]-cnta[i]); // 两者相减 +} +```) + +== 数学 + +=== 快速幂:$O(log n)$ + +Python中自带快速幂。 + +矩阵快速幂只需重载乘法。 + +#code_snippet(```cpp +int q_power(int a, int n) { + if (n == 0) return 1; + if (n == 1) return a; + int base = q_power(a, n / 2); + base *= base; + return (n % 2) ? a * base : base; +} +```) + +=== 费马小定理求幂的模:$O(log P)$ + +计算模意义下的幂。$p$必须为质数。因为$a^(p - 1) equiv 1 (mod p)$,因此$a^b equiv a^(b mod (p - 1)) (mod p)$ + +#code_snippet(```cpp +int q_power(int a, int n, int mod) { + int ans = 1, base = a; + while(n) { + if (n & 1) ans *= base; + base *= base; + ans %= mod; + base %= mod; + n >>=1; + } + return ans; +} + +int q_big_power(int a, int n, int p) { + return q_power(a, n % (p - 1), p) +} +```) + +=== 更快的快速幂:$O(T)$ + +在$a$不变的情况下进行$T$次幂查询$t_1, t_2, dots t_T$,可以记$n = max{t_i}$,则 +$ a^t = (a^(sqrt(n)))^(t \/ sqrt(n)) times a^(t % sqrt(n)) $ + +即,我们可以提前算好$a$的$0$到$sqrt(n)$次幂进行计算并存储,之后可以以$O(1)$的速度进行计算。 + +=== 最大公约数gcd:$O(log n)$ + +使用欧几里得算法。STL中提供了`__gcd(a, b)`。 + +#code_snippet(```cpp +inline int gcd(int a, int b) { + return b == 0 ? a: gcd(b, a % b); +} +```) + +快速gcd: +#code_snippet(```cpp +int kgcd(int a, int b) { + if (a == 0) return b; + if (b == 0) return a; + if (!(a & 1) && !(b &1)) return kgcd(a >> 1, b >> 1) << 1; + else if (!(b & 1)) return kgcd(a, b >> 1); + else if (!(a & 1)) return kgcd(a >> 1, b); + else return kgcd(abs(a - b), min(a, b)); +} +```) + +=== 最小公倍数lcm + +#code_snippet(```cpp +int lcm(int a, int b) { + return a * b / gcd(a, b) +} +```) + +=== 扩展欧几里得算法 + +可以解出$a x + b y = gcd(a, b)$的一组特解。 + +#code_snippet(```cpp +void exgcd(int a, int b, int &x, int &y) { + if (b == 0) { + x = 1; + y = 0; + return; + } + exgcd(b, a % b, y, x); + y -= a / b * x; +} +```) + +== 数位分解 + +=== 除余法 + +#code_snippet(```cpp +vector split(int n){ // 传入整数 + vector ret; + while(n){ + int t = n % 10; ret.push_back(t); + n /= 10; + } + reverse(ret.begin(), ret.end()); // 反转,按需 + return ret; +} +```) + +=== ASCII转数字 + +#code_snippet(```cpp +vector split(string n){ // 传入字符串 + vector ret; + ret.resize(n.size()); + for(int i = 0; i < n.size(); ++i) + ret[i] = n[i] - '0'; // 利用ASCII减法获得真实数字 + return ret; +} +```) + +=== 格雷码 + +格雷序列中的第$i$个项目的格雷码为$i xor (i >> 1)$。 + +#code_snippet(```cpp +vector Gray_Create(int n){ + vector res; res.clear(); + for(int i = 0; i < (1 << n); ++i) + res.push_back(i ^ (i >> 1)); + return res; +} +```) + +== 高精度类 + +#code_snippet(```cpp +struct BigInt{ // 仅限正整数,当MAXN较大时容易栈溢出,尽量定义为全局变量 + int digit[MAXN]; // [低位 -> 高位),与I/O顺序相反 + int SIZE, BASE; // 数位和进制 + + BigInt(){BASE = 10; SIZE = 0;} // 默认十进制 + BigInt(int base){BASE = base; SIZE = 0;} + BigInt(const string& S, int base = 10){ + SIZE = S.size(); + BASE = base; + string baseChar = "0123456789ABCDEF"; // 数位 + for (int i = 0, i < SIZE; i++) { + digit[i] = baseChar.find(S[i]); + } + } + void overflow(){ // 溢出进位 + for(int i = 0; i < SIZE; ++i) { + if(digit[i] >= BASE){ + if(i < SIZE - 1){ + digit[i + 1] += digit[i] / BASE; + digit[i] %= BASE; + } else{ + digit[SIZE++] = digit[i] / BASE; + digit[i] %= BASE; + } + } + } + } + + BigInt operator +(const BigInt &A){ // 高精度加法 + BigInt ret(BASE); // 采取前者的BASE,使用时注意保证两个数进制相同 + int max_size = max(SIZE, A.SIZE); + ret.SIZE = max_size; + for(int i =0; i < max_size; ++i){ + if(i < SIZE) ret.digit[i] += digit[i]; + if(i < A.SIZE) ret.digit[i] += A.digit[i]; + } + ret.overflow(); + return ret; + } + BigInt operator +(const int x){ // 普通加法 + BigInt ret = *this; + ret.digit[0] += x; + ret.overflow(); + return ret; + } + BigInt operator *(const BigInt &A){ // 高精度朴素乘法 O(n^2) + BigInt ret(BASE); + int max_size = SIZE + A.SIZE - 1; + ret.SIZE = max_size; + for(int i = 0; i < SIZE; ++i) + for(int j = 0; j < A.SIZE; ++j) + ret.digit[i + j] += digit[i] * A.digit[j]; + ret.overflow(); + return ret; + } + BigInt operator *(const int x){ // 普通乘法 + BigInt ret = *this; + for(int i = 0; i < SIZE; ++i) + ret.digit[i] *= x; + ret.overflow(); + return ret; + } + BigInt operator /(const int x){ // 普通除法 + BigInt ret(BASE); ret.SIZE = SIZE; + int remainder = 0; // 余数 + for(int i = SIZE - 1; i >= 0; --i){ // 高位 -> 低位 + int t = (remainder * BASE + digit[i]) / x; + int r = (remainder * BASE + digit[i]) % x; + ret.digit[ret.SIZE++] = t; remainder = r; + } + reverse(ret.digit, ret.digit + SIZE); // 反置为[低位 -> 高位) + while(ret.digit[ret.SIZE - 1] == 0 && ret.SIZE > 1) ret.SIZE--; // 去掉前缀0 + return ret; + } + int operator %(const int x){ // 普通模运算 + int remainder = 0; // 余数 + for(int i = SIZE - 1; i >= 0; --i) // 高位 -> 低位 + remainder = (remainder * BASE + digit[i]) % x; + return remainder; + } + bool operator ==(const BigInt &A){ + if(SIZE == A.SIZE){ + for(int i = SIZE -1; i >= 0; --i){ + if(digit[i] != A.digit[i]) return false; + } + return true; + } else return false; + } + bool operator <(const BigInt &A){ + if(SIZE == A.SIZE){ + for(int i = SIZE -1; i >= 0; --i){ + if(digit[i] < A.digit[i]) + return true; + else if(digit[i] > A.digit[i]) + return false; + } + return false; // 相等时返回false + } else return SIZE < A.SIZE; + } + bool operator <=(const BigInt &A){ + if(SIZE == A.SIZE){ + for(int i = SIZE -1; i >= 0; --i){ + if(digit[i] < A.digit[i]) + return true; + else if(digit[i] > A.digit[i]) + return false; + } + return true; // 相等时返回true + } else return SIZE < A.SIZE; + } +}; + +BigInt convert_to(BigInt A, int base){ // 进制转换,该方法存在BUG,慎用 + BigInt ret(base); + while(A.SIZE > 1 || A.digit[0] > 0){ // 保证A>0 + ret.digit[ret.SIZE++] = A % base; + A = A / base; + } + return ret; +} + +string baseChar = "0123456789ABCDEF"; // 数位 +char S[MAXN]; +istream& operator >>(istream &in , BigInt &A){ + scanf("%s", S); + A.SIZE = 0; A.BASE = 10; // 可调整输入进制 + for(int i = strlen(S) - 1; i >= 0; --i){ + A.digit[A.SIZE++] = baseChar.find(S[i]); + } + return in; +} +ostream& operator <<(ostream &out, const BigInt& A){ + for(int i = A.SIZE - 1; i >= 0; --i) + printf("%c", baseChar[A.digit[i]]); + return out; +} +```) + +== 最小生成树 + +=== Kruskal算法:$O(e log e)$ + +将所有的边按从小到大排列,依次取出。如果取到的边可以将两个不连通的部分联通,则选择它;如果取到的边连接的是已经连图的两个点,则不做操作。提前退出可以生成最小生成森林($n - k$次连接对应$k$棵树的$k-text("森林")$。 + +#code_snippet(```cpp +struct Edge{ // 带权边 + int from, to, dist; + Edge(int u, int v, int d): from(u), to(v), dist(d) {} + bool operator < (Edge x) const{ // const才能用PQ调用 + return dist > x.dist; //【最小】/最大支撑树 + } +}; +int n, m; +priority_queue PQ; // 按边权排序(默认大根堆) +uf_set U(MAXNODE); // 【并查集模板】 +int Kruskal(){ + int ret = 0, cnt = 0; + while(!PQ.empty()){ + Edge t = PQ.top(); PQ.pop(); // 取出最小边 + // cout << "dist:" <> n >> m; + for (int i = 0; i < m; i++) { + int x, y, z; cin >> x >> y >> z; + PQ.push(Edge(x, y, z)); + } + int ret = Kruskal(); + + if(ret == INF) cout << "orz" < +#include +#include +using namespace std; +constexpr int N = 5050, M = 2e5 + 10; + +struct E { + // v: 终点的编号 + // w: 权 + // x: 同起始点的下一个边在e[]中的编号 + int v, w, x; +} e[M * 2]; + +int n, m, h[N], cnte; + +// h[n] 为n号点为起始点的第一个边在e[]中的编号 + +// 最后一个加入的u起始的边将成为h[u] +void adde(int u, int v, int w) { e[++cnte] = E{v, w, h[u]}, h[u] = cnte; } + +// 以u为起点到达目前已生成树的一条边 +struct S { + int u, d; +}; + +// STL默认priority queue是大堆,这样可以使得它变为小堆 +bool operator<(const S &x, const S &y) { return x.d > y.d; } + +priority_queue q; +// dis[u]为u到当前最小树的最近距离 +int dis[N]; +bool vis[N]; + +int res = 0, cnt = 0; + +void Prim() { + memset(dis, 0x3f, sizeof(dis)); + dis[1] = 0; + q.push({1, 0}); + while (!q.empty()) { + if (cnt >= n) break; + int u = q.top().u, d = q.top().d; + q.pop(); + if (vis[u]) continue; + vis[u] = true; + ++cnt; + res += d; + for (int i = h[u]; i; i = e[i].x) { + int v = e[i].v, w = e[i].w; + if (w < dis[v]) { + dis[v] = w, q.push({v, w}); + } + } + } +} + +int main() { + cin >> n >> m; + for (int i = 1, u, v, w; i <= m; ++i) { + cin >> u >> v >> w, adde(u, v, w), adde(v, u, w); + } + Prim(); + if (cnt == n) + cout << res; + else + cout << "No MST."; + return 0; +} +```) + +== 最短路 + +=== Dijkstra算法:$O(e log n)$ + +将起点加入集合;找集合点向外连接的边中最短的边;将终点加入集合,并记录最短距离。 + +#code_snippet(```cpp +struct edge { + int v, w; +}; + +struct node { + int dis, u; + + bool operator>(const node& a) const { return dis > a.dis; } +}; + +vector e[MAXN]; +int dis[MAXN], vis[MAXN]; +priority_queue, greater> q; + +void dijkstra(int n, int s) { + memset(dis, 0x3f, (n + 1) * sizeof(int)); + memset(vis, 0, (n + 1) * sizeof(int)); + dis[s] = 0; + q.push({0, s}); + while (!q.empty()) { + int u = q.top().u; + q.pop(); + if (vis[u]) continue; + vis[u] = 1; + for (auto ed : e[u]) { + int v = ed.v, w = ed.w; + if (dis[v] > dis[u] + w) { + dis[v] = dis[u] + w; + q.push({dis[v], v}); + } + } + } +} +```) + +== 树状数组 + +#code_snippet(```cpp +int C[MAXN]; +int lowbit(int x) {return x&(-x);} // 计算x二进制下只保留最低位1后的值 +vector A(1,0); +struct BIT{ // 树状数组 + int n; + //所有数组统一从下标1开始使用!!! + BIT(vector& A){ // 初始化,O(nlogn) + n = A.size() - 1; + for(int i = 1; i < A.size(); ++i) + add(i, A[i]); // 从C[1]开始插入 + } + int sum(int x){ // 前缀和[1, x] + int ret = 0; + while(x > 0){ ret += C[x]; x-= lowbit(x);} + return ret; + } + int query(int L, int R){ // 查询操作,O(logn) + return sum(R) - sum(L-1); + } + void add(int x, int d){ // 修改操作,O(logn) + while(x <= n){ + C[x] += d; x += lowbit(x); + } + } +}; +```) + +== 线段树 + +与树状数组的基本思路类似,都是维护一段的信息。支持 +- `update(x, v)`,将$A_x$修改为$v$:$O(log n)$。 +- `query(L, R)`,求集合${A_L, A_(L + 1), dots, A_R}$的min,max,sum或者其它性质。这个性质必须满足结合律。 + +#code_snippet(```cpp +struct SegmentTree{ // 区间求和型,所有下标从1开始!!! + int n; // 元素个数 + int *a; + int d[2 * MAXN - 1]; // 保存节点信息 + SegmentTree(int N, int *A){ + n = N; a = A; // 传入初始数组 + build(1, n, 1); + } + void build(int s, int t, int p) { // build(1, n, 1) + // 对 [s,t] 区间建立线段树,当前根的编号为 p + if (s == t) { d[p] = a[s]; return;} + int m = (s + t) / 2; + build(s, m, p * 2), build(m + 1, t, p * 2 + 1); // 递归对左右区间建树 + d[p] = d[p * 2] + d[(p * 2) + 1]; // 【求和】 + } + void update(int x, int v, int s, int t, int p){ // 将A[x]修改为v + // update(x, v, 1, n, 1); + if(x == s && x == t) return; + d[p] += v - a[x]; a[x] = v; // 【更新】 + int m = (s + t) >> 1; + if (s <= x && x <= m) update(x, v, s, m, p * 2); + else update(x, v, m + 1, t, p * 2 + 1); + } + int query_sum(int le, int ri, int s, int t, int p) { // 计算区间和 + // query_sum(le, ri, 1, n, 1); + // [le,ri] 为查询区间,[s,t] 为当前节点包含的区间,p 为当前节点的编号 + if (le <= s && t <= ri) + return d[p]; // 当前区间为询问区间的子集时直接返回当前区间的和 + int m = (s + t) >> 1, sum = 0; + if (le <= m) sum += query_sum(le, ri, s, m, p * 2); + if (ri > m) sum += query_sum(le, ri, m + 1, t, p * 2 + 1); + return sum; + } +}; +```) + +== 并查集 + +#code_snippet(```cpp +#define MAXNODE 5005 +struct uf_set{ + int f[MAXNODE], SIZE; + int size[MAXNODE]; // 子树大小,初始为1 + uf_set(int s): SIZE(s) { + _for(i, 0, SIZE) f[i] = i; // i就在它本身的集合里 + _for(i, 0, SIZE) size[i] = 1; + } + int find(int x){ // ≈ O(!) + return (f[x] == x) ? x: f[x] = find(f[x]); // 路径压缩 + } + void Union(int x, int y){ + int xx = find(x), yy = find(y); + if (xx == yy) return; + if (size[xx] > size[yy]) //启发式合并,保证小的合到大的里 + swap(xx, yy); + f[xx] = yy; + size[yy] += size[xx]; + } +}; +```) \ No newline at end of file diff --git a/leetcodecheatsheet/img/三角形剖分.png b/leetcodecheatsheet/img/三角形剖分.png new file mode 100644 index 0000000000000000000000000000000000000000..c3b1568531cf4ab2aaa59a1d4b13bac15531d024 GIT binary patch literal 44898 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 literal 0 HcmV?d00001