CSP2025

· · 生活·游记

Day -???

我是 gesp 忠实用户!

充钱,不打 S 初赛了。

Day -???

报名 J 了。

Day -51

获得 J 准考证号 SD-J06994。

Day -42

考 J。

感觉 AK 了。

怎么有个题我记得选对了,但是誊抄到准考证那张纸的答案错了。不确定答题卡填的对不对。

怎么办,慌了。

算了,无所谓,肯定会过的。

Day -41

多虑了。

神秘 101 分,并非 F12。

ccf 的恩情还不完。

入门组成绩因技术原因统一多加3分,现已更正,请大家通知入门组重新查询成绩。因工作失误给大家带来不便,深感抱歉![表情][表情][表情]

98pts,并没 ak。

Day -10

获得准考证号,SD-J01372,SD-S00912。

Day -3

停课了。

写一下要打的板子,高强度复习几遍,加粗是要打的,虽然感觉没什么用:

图论:割边割点边双点双强连通分量欧拉路径dij

字符串:hash,kmp,exkmp,manacher,acam,sa。

ds:fenwick,smt1,smt2,smt3,trie,st 表,dsu,笛卡尔树

树:重心,直径,lca,树剖,淀粉质。

数学:bezout,exgcdcrt,筛,wilson,欧拉定理/扩展定理,二项式定理,catalan。

线代:矩阵快速幂高消

感觉有点烫,但是不考别的只能复习这些。

Day -2

颓,啥也没干。

Day -1

上午仍然颓。

下午去日照了。

因为【数据删除】晚上差点没有 j 组试机。

Day 0

上午 J。

30min AK 了,何意味。

罚坐 3h,无所事事,在草稿纸上发表神秘言论。

当 S 的热身赛了。

下午 S。

先开 T1。

首先,如果我们让所有人都选最满意的部门,最多会有一个部门的人数超了。

那么调整这个部门里的人。随便维护一下就行了。

正确性显然吧,咕了。

写完是 22min。

开 T2。

$m$ 是容易干掉的,我们发现对于一种状态,只有原来在最小生成树里的边和新加的边有用,于是 $nk2^k\log n$。 然后感觉干掉 $\log$ 就差不多了。 干掉 $\log$ 有一万种做法吧,可以归并,也可以把所有边放一块排序。 然后 $\log n$ 没了,但注意 kruskal 有个 $\alpha(n)$。 最后是 $nk2^k\alpha(n)$,大样例挺稳的,跑了。 写完大约 1h20min。 然后把 T3,T4 看了一遍,T3 是串串题,先跳。T4 显然 $O(n^3)$ dp 吧,他的特殊性质有何意义,看不懂。 回来赤 T3。我们发现查询的两个串有一段不相等的区间必须覆盖的,假设是 $[l,r]$。然后发明一个诡异 acam,字符集是 $26\times 26$,对模式串建 trie 然后搞 fail。 询问串放 acam 上跑,我们要的模式串是完全覆盖 $[l,r]$ 的,比较难做。我们可以省掉左端点的限制,然后从 $(l+1)$ 处再跑一遍,剪掉就行。 但是我不太擅长 acam,我只会 $|\Sigma|^2L$ 求 fail。 现场再次发明,我们对字符集分块,比较神秘,反正最后干到 $|\Sigma|L$ 了。 写完大约 2.5h。 还有 1.5h,优势在我。 开 D。 这种 dp 状态难点在于你不知道哪些人被选了。 神秘思路,我们先不计算不好算也不重要的人的贡献。 假如当前有 $x$ 个人失败,那么 $\le x$ 的人不必区分,而 $>x$ 的人不好处理。 那就不管这些人。 dp:$f_{i,j,k}$:选了 $i$ 个人,其中 $j$ 个失败了,选了 $k$ 个人的 $c>j$,并且只知道这 $k$ 个人 $c>j$,不知道他们具体是谁。 转移 trivial,瞪了一会大样例 2 才过。 感觉这个 T4 就是点啊,贡献后置的 trick 在 arc 见过。 然后惊恐发现大样例都水完了,于是造极限数据。 T3 本地跑 3s+,但是读入就 600ms,这我优化个吊啊。 不管了跑路了。 回去的车上知道了一个悲伤的事。逝者安息。 我该在哪里停留?我问我自己。 # Day 1 才知道 T3 询问串长度不等,那我不四万了。 【数据删除】 熨斗上 j ak 了,s $100+80+100+100$,sd rk14。 洛谷上 s $100+88+90+100$。 T2 问题不大,相信少爷机。 T3 卡就卡吧,给孩子留点分就行了。 想去冬令营,能赢吗? # Day 4 通过【数据删除】得到分数: J:$100+100+100+100=400$。 S:$100+80+100+100=380$。 S T2 的并查集没写按秩合并。 之前一直认为只路径压缩就是 $\alpha(n)$。但是只路径压缩或只按秩合并都是 $\log$,一起用才能 $\alpha(n)$。 严肃学习了。 ccf 还我 20 分!!! 算了,本质是没做到 $n2^k\alpha(n)$。 附代码: ::::info[J T1] ```cpp #include <bits/stdc++.h> using namespace std; int n; char s[1000005]; char ans[1000005]; int tot; int main() { freopen("number.in", "r", stdin); freopen("number.out", "w", stdout); cin >> s + 1; n = strlen(s + 1); for (int i = 1; i <= n; i++) { if (isdigit(s[i])) ans[++tot] = s[i]; } sort(ans + 1, ans + tot + 1); for (int i = tot; i; i--) putchar(ans[i]); return 0; } ``` :::: ::::info[J T2] ```cpp #include <bits/stdc++.h> using namespace std; int n, m; struct node { int val, id; } a[105]; bool cmp(node a, node b) { return a.val > b.val; } int main() { freopen("seat.in", "r", stdin); freopen("seat.out", "w", stdout); cin >> n >> m; for (int i = 1; i <= n * m; i++) { cin >> a[i].val; a[i].id = i; } sort(a + 1, a + n * m + 1, cmp); int p; for (int i = 1; i <= n * m; i++) { if (a[i].id == 1) { p = i; break; } } int a = (p - 1) / n; int b = (p - 1) % n + 1; if (a & 1) { cout << a + 1 << " " << (n - b + 1) << endl; } else { cout << a + 1 << " " << b << endl; } return 0; } ``` :::: ::::info[J T3] ```cpp #include <bits/stdc++.h> using namespace std; const int N = 500005; int n, k; int a[N], f[N], mp[1 << 20]; inline void rd(int &a, int c = 0) { while (!isdigit(c = getchar())); for (a = 0; isdigit(c); c = getchar()) a = (a << 3) + (a << 1) + (c ^ 48); } int main() { freopen("xor.in", "r", stdin); freopen("xor.out", "w", stdout); memset(mp, -1, sizeof(mp)); rd(n), rd(k); mp[0] = 0; for (int i = 1; i <= n; i++) { rd(a[i]); a[i] ^= a[i - 1]; if (~mp[a[i] ^ k]) { f[i] = f[mp[a[i] ^ k]] + 1; } mp[a[i]] = i; f[i] = max(f[i], f[i - 1]); } cout << f[n]; return 0; } ``` :::: ::::info[J T4] ```cpp #include <bits/stdc++.h> using namespace std; const int N = 5005, mod = 998244353; int n, a[N], f[N]; int main() { freopen("polygon.in", "r", stdin); freopen("polygon.out", "w", stdout); cin >> n; for (int i = 1; i <= n; i++) cin >> a[i]; sort(a + 1, a + n + 1); f[0] = 1; int ans = 0; for (int i = 1; i <= n; i++) { for (int j = a[i] + 1; j <= 5001; j++) ans = (ans + f[j]) % mod; for (int j = 5001; ~j; j--) f[min(j + a[i], 5001)] = (f[min(j + a[i], 5001)] + f[j]) % mod; } cout << ans; return 0; } ``` :::: ::::info[S T1] ```cpp #include <bits/stdc++.h> using namespace std; const int N = 100005; int n, a[N][3], cho[N]; priority_queue <int, vector <int>, greater <int> > q; inline void rd(int &a, int c = 0) { while (!isdigit(c = getchar())); for (a = 0; isdigit(c); c = getchar()) a = (a << 3) + (a << 1) + (c ^ 48); } void wrt(int x) { if (x > 9) wrt(x / 10); putchar(x % 10 ^ 48); } void solve() { int c0 = 0, c1 = 0, c2 = 0; rd(n); int ans = 0; for (int i = 1; i <= n; i++) { rd(a[i][0]), rd(a[i][1]), rd(a[i][2]); if (a[i][0] >= a[i][1] && a[i][0] >= a[i][2]) c0++, cho[i] = 0; else if (a[i][1] >= a[i][0] && a[i][1] >= a[i][2]) c1++, cho[i] = 1; else c2++, cho[i] = 2; ans += max(max(a[i][0], a[i][1]), a[i][2]); } if (c1 * 2 > n) { for (int i = 1; i <= n; i++) { swap(a[i][0], a[i][1]); if (cho[i] != 2) cho[i] ^= 1; } swap(c0, c1); } if (c2 * 2 > n) { for (int i = 1; i <= n; i++) { swap(a[i][0], a[i][2]); if (cho[i] != 1) cho[i] ^= 2; } swap(c0, c2); } while (q.size()) q.pop(); for (int i = 1; i <= n; i++) { if (cho[i] == 0) q.push(a[i][0] - max(a[i][1], a[i][2])); } while (c0 * 2 > n) { int x = q.top(); q.pop(); ans -= x; c0--; } wrt(ans), putchar(10); } int main() { freopen("club.in", "r", stdin); freopen("club.out", "w", stdout); int T; rd(T); while (T--) solve(); return 0; } ``` :::: :::info[S T2] ```cpp #include <bits/stdc++.h> using namespace std; const int N = 10005; typedef long long ll; bool Mbe; int n, m, k, x; struct edge { int u, v, w; } e[2000005]; int ect; int c[11]; struct DSU { int a[N + 10]; void init() { for (int i = 1; i <= n + 10; i++) a[i] = i; } int find(int k) { return k == a[k] ? k : a[k] = find(a[k]); } inline void merge(int u, int v) { a[find(u)] = find(v); } } f[1 << 10]; ll ans[1 << 10]; bool Med; inline void rd(int &a, int c = 0) { while (c = getchar(), c < 48 || c > 57); for (a = 0; c >= 48 && c <= 57; c = getchar()) a = (a << 3) + (a << 1) + (c ^ 48); } template <class T> void wrt(T x) { if (x > 9) wrt(x / 10); putchar(x % 10 ^ 48); } bool cmp(edge a, edge b) { return a.w < b.w; } int main() { // int _ = clock(); freopen("road.in", "r", stdin); freopen("road.out", "w", stdout); rd(n), rd(m), rd(k); for (int i = 1; i <= m; i++) { rd(e[i].u), rd(e[i].v), rd(e[i].w); } ect = m; for (int i = 1; i <= k; i++) { rd(c[i]); for (int j = 1; j <= n; j++) rd(x), e[++ect] = {n + i, j, x}; } // cerr << clock() - _ << endl; sort(e + 1, e + ect + 1, cmp); // cerr << clock() - _ << endl; for (int i = 0; i < (1 << k); i++) { f[i].init(); for (int j = 1; j <= k; j++) { if (i >> j - 1 & 1) ans[i] += c[j]; } } // cerr << clock() - _ << endl; for (int i = 1; i <= ect; i++) { if (e[i].u <= n) { int u = e[i].u, v = e[i].v, w = e[i].w; if (f[0].find(u) != f[0].find(v)) { for (int j = 0; j < (1 << k); j++) { if (f[j].find(u) != f[j].find(v)) { ans[j] += w; f[j].merge(u, v); } } } } else { int u = e[i].u, v = e[i].v, w = e[i].w; for (int j = 0; j < (1 << k); j++) { if (j >> u - n - 1 & 1) { if (f[j].find(u) != f[j].find(v)) { ans[j] += w; f[j].merge(u, v); } } } } } ll anss = 1e18; for (int i = 0; i < (1 << k); i++) anss = min(anss, ans[i]); wrt(anss); // cerr << clock() - _; return 0; } ``` :::: ::::info[S T3] ```cpp #include <bits/stdc++.h> using namespace std; const int N1 = 200005, N2 = 5000005; typedef long long ll; #define rep(i, a, b) for (int i(a); i <= (b); ++i) template <class T> inline void ckmn(T &a, T b) { (a > b) && (a = b); } template <class T> inline void ckmx(T &a, T b) { (a < b) && (a = b); } bool Mbe; int n, q, a[N2][26], b[N2][26], tot1, tot2; char s1[N2], s2[N2]; int f[N2], fail[N2]; int qu[N2], ql, qr; bool Med; inline void rd(int &a, int c = 0) { while (!isdigit(c = getchar())); for (a = 0; isdigit(c); c = getchar()) a = (a << 3) + (a << 1) + (c ^ 48); } template <class T> void wrt(T x) { if (x > 9) wrt(x / 10); putchar(x % 10 ^ 48); } void ins(int len) { int p = 0; rep(i, 1, len) { int c1 = s1[i] - 'a', c2 = s2[i] - 'a'; if (!a[p][c1]) a[p][c1] = ++tot1; if (!b[a[p][c1]][c2]) b[a[p][c1]][c2] = ++tot2; p = b[a[p][c1]][c2]; } f[p]++; } void build_acam() { ql = 1, qr = 0; rep(i, 0, 25) { if (!a[0][i]) continue; rep(j, 0, 25) { if (b[a[0][i]][j]) qu[++qr] = b[a[0][i]][j]; } } while (qr >= ql) { int u = qu[ql++]; // cout << "+ " << u << endl; rep(i, 0, 25) { // cout << u << " " << i << " " << a[u][i] << endl; if (!a[u][i]) continue; int p = fail[u]; while (p && !a[p][i]) p = fail[p]; rep(j, 0, 25) { int &v = b[a[u][i]][j]; // cout << u << " " << v << endl; if (v) fail[v] = b[a[p][i]][j], f[v] += f[fail[v]], qu[++qr] = v; else v = b[a[p][i]][j]; } } } } ll play(int len, int st, int tog) { int p = 0; ll ans = 0; rep(i, st, len) { int c1 = s1[i] - 'a', c2 = s2[i] - 'a'; while (p && !a[p][c1]) p = fail[p]; p = b[a[p][c1]][c2]; if (i >= tog) ans += f[p]; } return ans; } int main() { freopen("replace.in", "r", stdin); freopen("replace.out", "w", stdout); rd(n), rd(q); int sm1 = 0; rep(i, 1, n) { scanf("%s %s", s1 + 1, s2 + 1); // cout << " " << s1 + 1 << " " << s2 + 1 << endl; int len = strlen(s1 + 1); ins(len); sm1 += len; } build_acam(); // rep(i, 0, tot2) { // cout << i << " " << fail[i] << endl; // rep(j, 0, 25) { // rep(k, 0, 25) { // if (b[a[i][j]][k]) cout << i << " " << j << " " << k << " " << b[a[i][j]][k] << endl; // } // } // } int sm2 = 0; while (q--) { scanf("%s %s", s1 + 1, s2 + 1); int len = strlen(s1 + 1); sm2 += len; int mn = 1e9, mx = 0; rep(i, 1, len) { if(s1[i] != s2[i]) { ckmn(mn, i); ckmx(mx, i); } } // cout << mn << " " << mx << endl; wrt(play(len, 1, mx) - play(len, mn + 1, mx)), putchar(10); } // cerr << sm1 << " " << sm2; return 0; } ``` :::: ::::info[S T4] ```cpp #include <bits/stdc++.h> using namespace std; const int N = 505, mod = 998244353; typedef long long ll; #define rep(i, a, b) for (int i(a); i <= (b); ++i) #define repr(i, a, b) for (int i(a); i < (b); ++i) #define per(i, a, b) for (int i(a); i >= (b); --i) template <class T> inline void ckmn(T &a, T b) { (a > b) && (a = b); } template <class T> inline void ckmx(T &a, T b) { (a < b) && (a = b); } int n, m, s[N], t[N], p[N], x, f[N][N][N]; int fac[N], fiv[N]; inline void rd(int &a, int c = 0) { while (!isdigit(c = getchar())); for (a = 0; isdigit(c); c = getchar()) a = (a << 3) + (a << 1) + (c ^ 48); } void wrt(int x) { if (x > 9) wrt(x / 10); putchar(x % 10 ^ 48); } int qpw(int a, int b) { int R = 1; for (; b; b >>= 1) { if (b & 1) R = 1ll * R * a % mod; a = 1ll * a * a % mod; } return R; } void init() { rep(i, fac[0] = 1, 500) fac[i] = 1ll * fac[i - 1] * i % mod; fiv[500] = qpw(fac[500], mod - 2); per(i, 499, 0) fiv[i] = fiv[i + 1] * (i + 1ll) % mod; } inline void ad(int &a, ll b) { a = (a + b) % mod; } inline int C(int n, int m) { if (n < m || n < 0 || m < 0) return 0; return 1ll * fac[n] * fiv[m] % mod * fiv[n - m] % mod; } int main() { freopen("employ.in", "r", stdin); freopen("employ.out", "w", stdout); init(); rd(n), rd(m); rep(i, 1, n) { while (isspace(x = getchar())); s[i] = x ^ 48; } rep(i, 1, n) rd(x), t[x]++; p[0] = t[0]; rep(i, 1, n) p[i] = p[i - 1] + t[i]; // rep(i, 0, n) cout << t[i] << " "; cout << endl; // rep(i, 0, n) cout << p[i] << " "; cout << endl; // #define cha(a, b, c) ((a) == 3 && (b) == 2 && (c) == 0) f[0][0][0] = 1; repr(i, 0, n) { rep(j, 0, i) { rep(k, 0, i) { if (!f[i][j][k]) continue; // cout << i << " " << j << " " << k << " " << f[i][j][k] << endl; if (s[i + 1] == 0) { // lose men count: j + 1 rep(l, 0, min(t[j + 1], k)) { // c <= j: // count: p[j] - (i - k) // if (cha(i + 1, j + 1, k - l)) cout << i << " " << j << " " << k << " " << f[i][j][k] << " " << (p[j] - j) % mod * fac[t[j + 1]] % mod * fiv[t[j + 1] - l] % mod * C(k, l) % mod << endl; ad(f[i + 1][j + 1][k - l], 1ll * f[i][j][k] * (p[j] - (i - k)) % mod * fac[t[j + 1]] % mod * fiv[t[j + 1] - l] % mod * C(k, l)); // c = j+1, s.t. l != t[j+1] if (l != t[j + 1]) { // if (cha(i + 1, j + 1, k - l)) cout << i << " " << j << " " << k << " " << f[i][j][k] << " " << fac[t[j + 1]] % mod * fiv[t[j + 1] - l - 1] % mod * C(k, l) % mod << endl; ad(f[i + 1][j + 1][k - l], 1ll * f[i][j][k] * fac[t[j + 1]] % mod * fiv[t[j + 1] - l - 1] % mod * C(k, l)); } // c > j+1 // if (cha(i + 1, j + 1, k - l + 1)) cout << i << " " << j << " " << k <<" " << f[i][j][k] << " " << fac[t[j + 1]] % mod * fiv[t[j + 1] - l] % mod * C(k, l) % mod << endl; ad(f[i + 1][j + 1][k - l + 1], 1ll * f[i][j][k] * fac[t[j + 1]] % mod * fiv[t[j + 1] - l] % mod * C(k, l)); } } else { // c <= j // count: p[j] - (i - k) rep(l, 0, min(t[j + 1], k)) { // if (cha(i + 1, j + 1, k - l)) cout << i << " " << j << " " << k << " " << f[i][j][k] << " " << (p[j] - j) % mod * fac[t[j + 1]] % mod * fiv[t[j + 1] - l] % mod * C(k, l) % mod <<endl; ad(f[i + 1][j + 1][k - l], 1ll * f[i][j][k] * (p[j] - (i - k)) % mod * fac[t[j + 1]] % mod * fiv[t[j + 1] - l] % mod * C(k, l)); } // c > j // if (cha(i + 1, j, k + 1)) cout << i << " " << j << " " << k << " " << f[i][j][k] << " " << 1 << endl; ad(f[i + 1][j][k + 1], f[i][j][k]); } } } } // cout << " " << f[3][2][0] << endl; int ans = 0; rep(j, 0, n - m) { rep(k, 0, n) { if (f[n][j][k]) { if (p[j] + k == n) ad(ans, 1ll * f[n][j][k] * fac[k]); } } } wrt(ans); return 0; } ``` ::::