Mobile wallpaper 1Mobile wallpaper 2Mobile wallpaper 3Mobile wallpaper 4Mobile wallpaper 5
1265 字
6 分钟
2025春训第二场
2025-03-03
统计加载中...

考场上只做出来了 A、B、C,拼尽全力无法战胜数学题😭😭😭。

D 一开始想错了方向,各种分解质因数把自己搞头疼了都,事后暴力莽出来了;E 事后打表打了 20min 以惊人的毅力拿下(别急,还有反转)。

A. 矩形#

把三个矩形的左下角坐标取 max,右上角坐标取 min,就是重叠部分的矩形。

  • ps:注意判断是否重叠,否则不重叠的可能会负负得正,然后 WA.
#include <iostream>
using namespace std;
int main() {
ios::sync_with_stdio(0);
cin.tie(0), cout.tie(0);
long long x1, y1, x2, y2;
long long a1, b1, a2, b2;
cin >> x1 >> y1 >> x2 >> y2;
cin >> a1 >> b1 >> a2 >> b2;
x1 = max(x1, a1), y1 = max(y1, b1), x2 = min(x2, a2), y2 = min(y2, b2);
cin >> a1 >> b1 >> a2 >> b2;
x1 = max(x1, a1), y1 = max(y1, b1), x2 = min(x2, a2), y2 = min(y2, b2);
if (x2 - x1 <= 0 || y2 - y1 <= 0) cout << 0 << endl;
else cout << max(0ll, (x2 - x1) * (y2 - y1)) << endl;
return 0;
}

这么水的题还有人用 AI 写,还被抓了😲.

B. 全球通勤#

每条边的 VIP 是相互独立的,直接差分前缀和统计每条边经过的次数,最后遍历一次算出来每条边的最优解加起来即可。

  • ps:注意 l 可能大于 r,可能需要 swap 一下。
#include <cstdio>
#include <iostream>
using namespace std;
const int N = 5000010;
int a[N], b[N], c[N];
int t[N];
int main() {
int n, m;
scanf("%d%d", &n, &m);
for (int i = 1; i < n; ++i) {
scanf("%d%d%d", &a[i], &b[i], &c[i]);
}
while (m--) {
int l, r;
scanf("%d%d", &l, &r);
if (l > r) swap(l, r);
t[l]++, t[r]--;
}
long long res = 0;
for (int i = 1; i < n; ++i) {
t[i] += t[i - 1];
res += min(t[i] * a[i], t[i] * c[i] + b[i]);
}
printf("%lld\n", res);
return 0;
}

C. 社交网络#

不能继续执行操作的情况只有一种,任何一个点所在的连通块都是完全图。所以直接找连通块,统计连通块的点数和边数算出每个连通块的操作次数累加即可。

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
const int N = 200010;
vector<int> ed[N];
int id[N], tot;
int cnt[N], ed_cnt[N];
void dfs(int x) {
if (id[x]) return;
id[x] = tot;
cnt[tot]++;
for (int y : ed[x]) {
dfs(y);
}
}
int main() {
int n, m;
scanf("%d%d", &n, &m);
for (int i = 0; i < m; ++i) {
int x, y;
scanf("%d%d", &x, &y);
ed[x].push_back(y);
ed[y].push_back(x);
}
for (int i = 1; i <= n; ++i) {
sort(ed[i].begin(), ed[i].end());
ed[i].erase(unique(ed[i].begin(), ed[i].end()), ed[i].end());
}
for (int i = 1; i <= n; ++i) {
if (!id[i]) {
++tot;
dfs(i);
}
}
for (int i = 1; i <= n; ++i) {
ed_cnt[id[i]] += ed[i].size();
}
long long res = 0;
for (int i = 1; i <= tot; ++i) {
res += (long long)cnt[i] * (cnt[i] - 1) / 2 - ed_cnt[i] / 2;
}
cout << res << endl;
return 0;
}

D. 数数#

我的做法有点暴力,但是时间复杂度是没有问题的。

  • 首先考虑暴力如何解决,直接枚举指数 i in [2, 60],底数 j in [1, n1in^{\frac{1}{i}}],把所有 jij^i去重统计个数。

  • 不难发现暴力的瓶颈在 n\sqrt{n} 上,如果 i 从 3 开始枚举,那么就不会 TLE,所以干脆直接从 3 枚举,如果 jij^i,是平方数就直接忽略,最后一次性加进去一个 n\sqrt n 即可。

  • n = 1e18 时时间复杂度是 1e6 级别的, 完全可行。

#include <iostream>
#include <cmath>
#include <unordered_set>
using namespace std;
long long power(long long n, long long p) {
long long res = 1, base = n;
while (p) {
if (p & 1) res = res * base;
base = base * base;
p >>= 1;
}
return res;
}
unordered_set<long long> s;
int main() {
long long n;
cin >> n;
for (int i = 60; i >= 3; --i) {
for (int j = (long long)pow(n, 1.0 / i); j; --j) {
long long t = power(j, i);
if (power((int)sqrt(t), 2) != t) s.insert(t);
}
}
cout << s.size() + (int)(sqrt(n) + 1e-9) << endl;
return 0;
}

E. 出题 (problem)#

我能力不足,找不到选择策略,只能暴搜了😭

  • **迭代加深:**因为要求方案字典序最小,所以必须优先搜小的,然而优先搜小的可能会导致递归层数增长过快爆栈或者 TLE,所以用迭代加深一步步试探可行性更高。

  • 剪枝1: 当前序列最后一位大于 n 时,直接不用搜了。

  • 剪枝2: 当前序列最后一位的 2^cnt 倍小于 n 时,一定不合法,即使不断翻倍也无法在指定步数内到达 n。(其中cnt = 后续空位数)

#include <iostream>
#include <vector>
using namespace std;
int cur[20];
int n;
bool dfs(int x, int d) {
if (x > d) {
if (cur[x - 1] == n) return true;
else return false;
}
if (cur[x - 1] > n || (long long)cur[x - 1] * (1 << (d - x + 1)) < n) return false;
for (int i = 0; i < x; ++i) {
for (int j = 0; j <= i; ++j) {
if (cur[i] + cur[j] > cur[x - 1]) {
cur[x] = cur[i] + cur[j];
if (dfs(x + 1, d)) return true;
}
}
}
return false;
}
int main() {
scanf("%d", &n);
int l;
cur[0] = 1;
for (l = 1; !dfs(1, l); ++l);
for (int i = 1; i <= l; ++i) {
printf("%d ", cur[i]);
}
printf("\n");
return 0;
}

WARNINGS#

  • 不要用 vector 频繁 push_back 和 pop_back,会严重超时!!!害我打了 20min 表

  • 注意常数优化,能算一次就不算第二次,否则搜索规模会指数级扩大。

F. 连续段 (row)#

这道题目前 0/0,我量力而为💔

2025春训第二场
https://starlab.top/posts/2025st2/
作者
Star
发布于
2025-03-03
许可协议
CC BY-NC-SA 4.0

部分信息可能已经过时