constint N = 100010; int son[N][26], cnt[N], idx; char str[N];
voidinsert(char str[]) { int p = 0; for (int i = 0; str[i] != 0; i++) { int u = str[i] - 'a'; if (!son[p][u]) son[p][u] = ++idx; p = son[p][u]; } cnt[p]++; }
intquery(char str[]) { int p = 0; for (int i = 0; str[i] != 0; i++) { int u = str[i] - 'a'; if (!son[p][u]) return0; p = son[p][u]; } return cnt[p]; }
int st[N]; int primes[N], idx = 0; voidsieve(int n = N - 5) { memset(st, 1, sizeof(st)); st[1] = st[0] = 0; for (int i = 2; i <= n; i++) { if (st[i]) primes[idx++] = i; for (int j = 0; i * primes[j] <= n; j++) { st[i * primes[j]] = false; if (i % primes[j] == 0) break; } } }
int c[N]; for (int i = 0; i < idx; i++) { int s = n, p = primes[i]; while (s) { c[i] += s / p; s /= p; } }
组合数
1 2 3 4 5 6 7 8 9 10
constint N, MOD; int c[N][N]; intget_cab(int a, int b) { if (c[a][b] != -1) return c[a][b]; if (b == 0 || a == b) return c[a][b] = 1; return c[a][b] = (get_cab(a - 1, b) + get_cab(a - 1, b - 1)) % MOD; }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
using ll = longlong; constint N, MOD; int fact[N]; int infact[N]; voidinit() { fact[0] = infact[0] = 1; for (int i = 1; i < N; i++) { fact[i] = (ll)fact[i - 1] * i % MOD; infact[i] = (ll) } } intget_cab(int a,int b) {
constint N; constdouble eps = 1e-6; int n; double a[N][N];
intgauss() { int c, r; for (c = 0, r = 0; c < n; c++) // 枚举每一列 { int t = r; for (int i = r; i < n; i++) // 找到绝对值最大的一行 if (fabs(a[i][c]) > fabs(a[t][c])) t = i;
if (fabs(a[t][c]) < eps) // 如果最大值是0, 忽略这一行 continue;
for (int i = c; i < n + 1; i++) // 把这一行换到最上面 swap(a[t][i], a[r][i]);
for (int i = n; i >= c; i--) //将第一个数变成1 a[r][i] /= a[r][c];
for (int i = r + 1; i < n; i++) //将下面所有行的第c列清零 if (fabs(a[i][c]) > eps) for (int j = n; j >= c; j--) a[i][j] -= a[r][j] * a[i][c]; r++; }
if (r < n) { for (int i = r; i < n; i++) if (fabs(a[i][n]) > eps) return2; // 无解 return1; // 无穷多解 }
for (int i = n - 1; i >= 0; i--) for (int j = i + 1; j < n; j++) a[i][n] -= a[i][j] * a[j][n];
booltopsort() { int cnt = 0; queue<int> q; for (int i = 1; i <= n; i++) if (din[i] == 0) { din[i]--; q.push(i); topo.push(i); cnt++; } while(q.size()) { int u = q.front(); q.pop(); for (int i = h[u]; i != -1; i = ne[i]) { int v = e[i]; din[v]--; if (din[v] == 0) { q.push(i); topo.push(i); cnt++; } } } return cnt == n; }
for (int i = 0; i < n - 1; i ++ ) { int u = -1; // 在还未确定最短路的点中,寻找距离最小的点 for (int j = 1; j <= n; j ++ ) if (!st[j] && (u == -1 || dist[u] > dist[j])) u = j;
// 如果第n次迭代仍然会松弛三角不等式,就说明存在一条长度是n+1的最短路径,由抽屉原理,路径中至少存在两个相同的点,说明图中存在负权回路。 for (int i = 0; i < n; i ++ ) { for (int j = 0; j < m; j ++ ) { int a = edges[j].a, b = edges[j].b, w = edges[j].w; if (dist[b] > dist[a] + w) dist[b] = dist[a] + w; } }
if (dist[n] > 0x3f3f3f3f / 2) return-1; return dist[n]; }
while (q.size()) { auto u = q.front(); q.pop(); st[u] = false;
for (int i = h[u]; i != -1; i = ne[i]) { int v = e[i]; if (dist[v] > dist[u] + w[i]) { dist[v] = dist[u] + w[i]; if (!st[v]) // 如果队列中已存在j,则不需要将j重复插入 { q.push(v); st[v] = true; } } } }
if (dist[n] == 0x3f3f3f3f) return-1; return dist[n]; }
floyd算法
考虑到任何一条路径都可以转化为两条更短的路径,所以通过枚举拆分路径的方式维护最短路。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
voidinit() { for (int i = 1; i <= n; i ++ ) for (int j = 1; j <= n; j ++ ) if (i == j) d[i][j] = 0; else d[i][j] = 0x3f3f3f3f; }
// 算法结束后,d[a][b]表示a到b的最短距离 voidfloyd() { for (int k = 1; k <= n; k ++ ) for (int i = 1; i <= n; i ++ ) for (int j = 1; j <= n; j ++ ) d[i][j] = min(d[i][j], d[i][k] + d[k][j]); }
intkruskal() { for (int i = 1; i <= n; i++) p[i] = i; sort(edges + 1, edges + m + 1, [](Edge a, Edge b) -> bool { return a.w < b.w; }); int sum = 0; for (int i = 1; i <= m; i++) { int a = edges[i].a, b = edges[i].b, w = edges[i].w; if (find(a) != find(b)) { add(a, b); sum += w; } } return sum; }
booldfs(int u, int c) { color[u] = c; for (int i = h[u]; i != -1; i = ne[i]) { int v = e[i]; if (!color[v]) { if (!dfs(v, 3 - c)) returnfalse; } elseif (color[v] == c) returnfalse; } returntrue; }
voidbfs(int r) { memset(depth, 0x3f, sizeof(depth)); depth[0] = 0, depth[r] = 1; queue<int> q; q.push(r); while (q.size()) { int u = q.front(); q.pop(); for (int i = h[u]; i != -1; i = ne[i]) { int v = e[i]; if (depth[v] > depth[u] + 1) { depth[v] = depth[u] + 1; q.push(v); fa[v][0] = u; for (int k = 1; fa[v][k - 1]; k++) fa[v][k] = fa[fa[v][k - 1]][k - 1]; } } } }
intlca(int a, int b) { if (depth[a] < depth[b]) swap(a, b); for (int k = K; k >= 0; k--) if (depth[fa[a][k]] >= depth[b]) a = fa[a][k]; if (a == b) return a; for (int k = K; k >= 0; k--) if (fa[a][k] != fa[b][k]) a = fa[a][k], b = fa[b][k]; return fa[a][0]; }
intget_days(int month, int year) { if (month == 2) return months[2] + is_leap(year); return months[month]; }
intmain() { int a, b, c, y1, y2; cin >> a >> b >> c >> y1 >> y2; int days = 0; for (int year = 1850; year <= y2; year++) { for (int month = 1; month <= 12; month++) { if (year >= y1 && month == a) { int w = (1 + days) % 7, cnt = 0; for (int d = 1; d <= get_days(month, year); d++) { if (w == c - 1) { cnt++; if (cnt == b) { printf("%04d/%02d/%02d\n", year, month, d); break; } } w = (w + 1) % 7; } if (cnt < b) { puts("none"); } } days += get_days(month, year); } } }