2026 CSP寄
Ashankamiko · · 生活·游记
CSP-J
本来想着玩玩吧,不要过度用脑,下午发挥。然而我并没有 AK。
T1
什么玩意。
T2
一开始想着不会直接暴力建字符串吧,然后看完数据范围花费
T3
一开始想着枚举二进制位直接填答案,然后把这个过程想成
T4
毁了。
QAQ,算了我不管 J 组。
CSP-S
T1
一开始写了个二分,二分最后的数,最后一个大样例没过。卡了好久,后来想到,或许我需要二分答案,然后二分最后的数?时间复杂度
如果最后一个数可以是
a_i+k,k>0 ,那么这些数全部减k 同样可以满足,而且花费更少。
然后我们在二分最终的数的时候就可以从
后来突然想到了可以直接二分答案,检查连续的区间,时间复杂度
T2
什么玩意啊,我读了
T3
很容易想到直接
void solve() {
in >> n >> d;
for (int i = 1; i <= n; i++) in >> x[i], e[i].clear();
for (int i = 1; i <= n; i++)
for (int j = i + 1; j <= n; j++)
if (x[j] - x[i] <= d) e[i].push_back(j), e[j].push_back(i);
else break;
int ans = 0;
for (int s = 1; s <= n; s++) {
for (int i = 1; i <= n; i++) f[i] = 0, dis[i] = 1e9;
dis[s] = 0, f[s] = 1, q.push(s);
while (!q.empty()) {
int u = q.front(); q.pop();
for (int v : e[u])
if (dis[u] + 1 < dis[v]) dis[v] = dis[u] + 1, q.push(v), f[v] = f[u];
else if (dis[u] + 1 == dis[v]) f[v] += f[u];
}
for (int i = 1; i <= n; i++) ans += f[i] == 2;
}
out << ans / 2 << '\n';
}
跑样例3的时候有点慢,当时认为这是
T4
什么玩意啊,怼着题面看了
回补 T2
我明白了,对于一条线,我们在线上切换不计代价,所以我们完全可以跑任意两条线间的最短路,Floyd 即可,
评价:真难调,真雷霆。
回补 T3
我突然发现 bfs 的时间复杂度其实是 break,直接二分最后一个满足
void solve() {
in >> n >> d;
for (int i = 1; i <= n; i++) in >> x[i];
for (int i = 1; i <= n; i++) {
pos[i] = i;
for (int j = i + 1; j <= n; j++)
if (x[j] - x[i] <= d) pos[i] = j;
else break;
}
int ans = 0;
for (int s = 1; s <= n; s++) {
for (int i = s + 1; i <= n; i++) f[i] = 0, dis[i] = 1e9;
dis[s] = 0, f[s] = 1, q.push(s);
while (!q.empty()) {
int u = q.front(); q.pop();
for (int v = pos[u]; v > u; v--)
if (dis[u] + 1 > dis[v]) break;
else if (dis[u] + 1 < dis[v]) dis[v] = dis[u] + 1, q.push(v), f[v] = f[u];
else if (dis[u] + 1 == dis[v]) f[v] += f[u];
}
for (int i = s + 1; i <= n; i++) ans += f[i] == 2;
}
out << ans << '\n';
}
T4
或许我们可以进行这样的一个树形 DP。
预估分数
S:本来是
J:
感觉还不错,要是 S 组的 T4 暴力没写错就真的满意了。