C++中关于数学的一些语法回忆(1)
一、头文件与常用常量1. 常用头文件竞赛里最常见#include bits/stdc.h using namespace std;如果你不用万能头也可以知道数学函数主要来自#include cmath2. 常用常量piC 标准里不一定直接给你pi竞赛中一般自己写const double PI acos(-1.0);这个很常用。3. 无穷大整型无穷大const int INF 0x3f3f3f3f;长整型无穷大const long long INFLL 0x3f3f3f3f3f3f3f3f;二、基本数值类型1. 整数int a; long long b;竞赛建议普通范围int数据可能到 (10^9) 以上乘法优先long long例如long long x 1LL * a * b;这里1LL很重要防止爆int。2. 浮点数double x; long double y;常用建议一般几何、概率、数学计算double要求更高精度时long double三、绝对值、最大最小值、交换1. 绝对值abs(x)注意int/long long都能用abs浮点数更稳妥写fabs(x)例如cout abs(-5) endl; // 5 cout fabs(-3.14) endl; // 3.142. 最大值最小值max(a, b) min(a, b)多个数可嵌套max(a, max(b, c));或者 C11max({a, b, c}); min({a, b, c});3. 交换swap(a, b);四、平方、开方、幂函数1. 平方竞赛里推荐直接写x * x不推荐pow(x, 2)因为pow更慢而且返回浮点数整数题里可能出精度问题。2. 开平方sqrt(x)例如double d sqrt(25.0); // 53. 幂函数pow(a, b)表示 (a^b)例如cout pow(2, 3) endl; // 8注意pow返回的是浮点数不适合拿来做整数精确判断。比如不要随便写if (pow(2, 10) 1024) ...整数幂更推荐自己写快速幂。五、取整、四舍五入1. 向下取整floorfloor(x)例如floor(3.9) 3 floor(-3.9) -42. 向上取整ceilceil(x)例如ceil(3.1) 4 ceil(-3.1) -33. 四舍五入roundround(x)例如round(3.6) 4 round(3.4) 34. 正数四舍五入常见写法(long long)(x 0.5)只适合你确定x 0的情况。六、三角函数与反三角函数这些在几何题里特别常见。1. 正弦、余弦、正切sin(x) cos(x) tan(x)注意参数是弧度不是角度。例如cout sin(PI / 2) endl; // 12. 反三角函数asin(x) acos(x) atan(x)例如cout atan(1.0) endl; // π/43.atan2(y, x)这个极其重要。atan2(y, x)作用求点(x, y)相对原点的极角。比atan(y / x)更好因为能判断象限不怕除零是竞赛求角度的标准写法七、余数、整除、取模1. 整除a / b如果a和b都是整数那么结果也是整数自动向 0 取整。例如7 / 3 2 -7 / 3 -22. 取模a % b例如7 % 3 1注意负数取模结果和语言实现规则有关竞赛里最好少依赖负模的符号。如果要保证非负常写((a % mod) mod) % mod八、最大公约数与最小公倍数1. 最大公约数gcdC17 可以直接用gcd(a, b)完整写法通常是#include numeric cout gcd(a, b);但很多平台bits/stdc.h也能用。2. 最小公倍数lcmlcm(a, b)或者自己写a / gcd(a, b) * b注意顺序先除后乘防止溢出。3. 手写欧几里得算法long long gcd_ll(long long a, long long b) { return b 0 ? a : gcd_ll(b, a % b); }这个很常考。九、快速幂这是竞赛数学必备。1. 普通快速幂long long qpow(long long a, long long b) { long long res 1; while (b) { if (b 1) res * a; a * a; b 1; } return res; }求 (a^b)2. 模意义下快速幂long long qpow(long long a, long long b, long long mod) { long long res 1 % mod; a % mod; while (b) { if (b 1) res res * a % mod; a a * a % mod; b 1; } return res; }这个在组合数、逆元、数论题里非常高频。十、质数相关1. 判断质数bool isPrime(int n) { if (n 2) return false; for (int i 2; 1LL * i * i n; i) { if (n % i 0) return false; } return true; }注意这里写1LL * i * i n防止溢出。2. 埃氏筛const int N 1000000; bool is_prime[N 1]; void sieve() { fill(is_prime, is_prime N 1, true); is_prime[0] is_prime[1] false; for (int i 2; i * i N; i) { if (is_prime[i]) { for (int j i * i; j N; j i) { is_prime[j] false; } } } }十一、组合数与阶乘1. 阶乘long long fact(int n) { long long res 1; for (int i 1; i n; i) res * i; return res; }2. 组合数简单写法long long C(int n, int k) { if (k n) return 0; if (k 0 || k n) return 1; long long res 1; for (int i 1; i k; i) { res res * (n - i 1) / i; } return res; }十二、对数函数1. 自然对数log(x)表示 (\ln x)2. 以 10 为底的对数log10(x)3. 以 2 为底的对数常见写法log2(x)不过有时竞赛中会自己处理避免精度问题。十三、随机数有时模拟题会用。1. 老写法rand()范围较差不太推荐高质量随机。2. 竞赛更常见写法mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());生成某个区间随机数cout rng() % 100 endl;或者uniform_int_distributionint dist(1, 100); cout dist(rng) endl;十四、精度控制输出1. 保留若干位小数cout fixed setprecision(6) x endl;需要头文件#include iomanip例如cout fixed setprecision(2) 3.14159 endl; // 3.14十五、比较浮点数浮点数不能随便直接判等。错误写法if (a b)正确写法const double eps 1e-9; if (fabs(a - b) eps)十六、位运算里的数学常用写法1. 判断奇偶if (x 1)奇数为真。2. 除以 2x 13. 乘以 2x 14. 判断第 k 位是否为 1if ((x k) 1)十七、常见数学模板小结1. gcd / lcmlong long gcd_ll(long long a, long long b) { return b ? gcd_ll(b, a % b) : a; } long long lcm_ll(long long a, long long b) { return a / gcd_ll(a, b) * b; }2. 快速幂long long qpow(long long a, long long b, long long mod) { long long res 1 % mod; a % mod; while (b) { if (b 1) res res * a % mod; a a * a % mod; b 1; } return res; }3. 判断平方数bool isSquare(long long x) { long long r sqrt(x); return r * r x || (r 1) * (r 1) x; }因为sqrt有时会有精度误差所以多判一下。十八、竞赛中最容易踩坑的点1.pow不适合整数精确计算比如pow(2, 60)可能有精度问题。2.sqrt后直接转整数要小心例如判断平方数时不能只写long long r sqrt(x); if (r * r x)最好多检查相邻值。3. 整数除法不是实数除法3 / 2 1如果你想要1.5必须写3.0 / 2或者(double)3 / 24.atan2(y, x)别写反是先y后x。5. 浮点比较用eps别迷信十九、你最该先背熟的竞赛数学 C 语法如果你现在只想先抓高频优先记这些sqrt(x) // 开方 abs(x), fabs(x) // 绝对值 max(a,b), min(a,b) gcd(a,b), lcm(a,b) pow(a,b) // 幂少用于整数精确 floor(x), ceil(x), round(x) sin(x), cos(x), tan(x) asin(x), acos(x), atan(x), atan2(y,x)以及这些写法const double PI acos(-1.0); const double eps 1e-9; 1LL * a * b cout fixed setprecision(6);二十、给你一个竞赛数学常用模板#include bits/stdc.h using namespace std; const double PI acos(-1.0); const double eps 1e-9; const long long INFLL 0x3f3f3f3f3f3f3f3f; long long gcd_ll(long long a, long long b) { return b ? gcd_ll(b, a % b) : a; } long long lcm_ll(long long a, long long b) { return a / gcd_ll(a, b) * b; } long long qpow(long long a, long long b, long long mod) { long long res 1 % mod; a % mod; while (b) { if (b 1) res res * a % mod; a a * a % mod; b 1; } return res; } bool isPrime(long long n) { if (n 2) return false; for (long long i 2; i * i n; i) { if (n % i 0) return false; } return true; } int main() { double x 3.1415926; cout fixed setprecision(6) x \n; return 0; }