以下全都是一起参加ACM的队友的代码,我自己写的全都因为电脑重装系统没了,感谢队友。:innocent::pray:
打表 分为离线打表和在线打表,看oj平台和比赛要求吧,一般都是在线打,除非计算量很大的就离线打。
看了下代码,好像用的蛮多的都是关于素数的,用到欧拉筛。
动态规划 推荐:【宫水三叶】深度讲解背包问题
dp 树上dp 状压dp 搜索树 用得差不多,DFS多一点
BFS DFS 并查集 单调栈与单调队列 前缀与差分 。。。
备注:
感觉往下的用的都很少了,只针对特别的题目有用,有兴趣的自行查阅
分块算法 吉司机线段树 维护区间最大值mx,区间中最大值出现次数tot,区间中的次大值se,区间和sum
扩展欧几里得与逆元 模线性方程组 欧拉函数 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 typedef long long ll;#define N 1000100 ll phi[N], d[N]; void ini () { memset (isPrime, true , sizeof (isPrime)); int i, j; for (i = 2 ; i < N; i++) { if (isPrime[i]) prime[cnt++] = i, phi[i] = i - 1 ; for (j = 0 ; j < cnt && i * prime[j] < N; j++) { isPrime[i * prime[j]] = 0 ; if (i % prime[j] == 0 ) { phi[i * prime[j]] = phi[i] * prime[j]; break ; } phi[i * prime[j]] = phi[i] * phi[prime[j]]; } } j = 2 ; for (i = 1 ; i < 1000003 ; i++) { if (phi[j] >= i) d[i] = j; else j++, i--; } }
区间与环形dp 生成树 最短路 LCA Miller_rabin和Rollard rho 大数乘和大数幂作为基础函数
Miller_rabin 判断一个数是否是素数,好像是99.99%的正确率?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 ll quick_mul (ll a, ll b, ll m = mod) { ll ret = 0 ; while (b) { if (b & 1 ) ret = (ret + a) % m; b >>= 1 ; a = (a << 1 ) % m; } return ret; } ll quick_pow (ll a, ll b, ll m = mod) { ll ret = 1 ; while (b) { if (b & 1 ) ret = quick_mul (ret, a, m); b >>= 1 ; a = quick_mul (a, a, m); } return ret; } bool Miller_Rabin (ll p) { ll n = 0 , m = p - 1 ; if (p == 2 ) return true ; if (p < 2 || !(p & 1 )) return false ; while (!(m & 1 )) n++, m >>= 1 ; for (int i = 0 ; i < 10 ; i++) { ll x = rand () % (p - 1 ) + 1 ; x = quick_pow (x, m, p); for (int j = 0 ; j < n; j++) { ll x1 = quick_mul (x, x, p); if (x1 == 1 && x != 1 && x != p - 1 ) return false ; x = x1; } if (x != 1 ) return false ; } return true ; }
Pollard rho 快速找到大整数的一个非1、非自身的因子的算法。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 ll quick_mul (ll a, ll b, ll m = mod) { ll ret = 0 ; while (b) { if (b & 1 ) ret = (ret + a) % m; b >>= 1 ; a = (a << 1 ) % m; } return ret; } ll quick_pow (ll a, ll b, ll m = mod) { ll ret = 1 ; while (b) { if (b & 1 ) ret = quick_mul (ret, a, m); b >>= 1 ; a = quick_mul (a, a, m); } return ret; } ll gcd (ll a, ll b) { return b == 0 ? a : gcd (b, a % b); } ll f (ll x, ll c, ll n) { return (quick_mul (x, x, n) + c) % n; } ll Pollard_Rho (ll n) { if (n == 4 ) return 2 ; ll f1 = 0 , f2 = 0 ; while (1 ) { ll c = rand () % (n - 1 ) + 1 ; do { for (int i = 0 ; i < 128 ; i++) { f1 = f (f1, c, n); f2 = f (f (f2, c, n), c, n); if (f1 == f2) break ; ll d = gcd (abs (f1 - f2), n); if (d > 1 ) return d; } } while (f1 != f2); } }
ZKW线段树 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 ll sum[N << 2 ], lazy[N << 2 ]; void build () { int i; for (m = 1 ; m <= n; m <<= 1 ) ; for (i = 1 ; i <= n; i++) cin >> sum[m + i]; for (i = m - 1 ; i; i--) sum[i] = sum[i << 1 ] + sum[(i << 1 ) | 1 ]; } void upd (int l, int r, ll v) { ll lc = 0 , rc = 0 , len = 1 ; for (l += m - 1 , r += m + 1 ; l ^ r ^ 1 ; l >>= 1 , r >>= 1 , len <<= 1 ) { if (~l & 1 ) lazy[l ^ 1 ] += v, lc += len; if (r & 1 ) lazy[r ^ 1 ] += v, rc += len; sum[l >> 1 ] += v * lc; sum[r >> 1 ] += v * rc; } for (lc += rc, l >>= 1 ; l; l >>= 1 ) sum[l] += v * lc; } ll query (int l, int r) { ll ans = 0 , lc = 0 , rc = 0 , len = 1 ; for (l += m - 1 , r += m + 1 ; l ^ r ^ 1 ; l >>= 1 , r >>= 1 , len <<= 1 ) { if (~l & 1 ) ans += sum[l ^ 1 ] + len * lazy[l ^ 1 ], lc += len; if (r & 1 ) ans += sum[r ^ 1 ] + len * lazy[r ^ 1 ], rc += len; ans += lc * lazy[l >> 1 ] + rc * lazy[r >> 1 ]; } for (lc += rc, l >>= 1 ; l; l >>= 1 ) ans += lc * lazy[l]; return ans; }