Mobile wallpaper 1Mobile wallpaper 2Mobile wallpaper 3Mobile wallpaper 4Mobile wallpaper 5
1811 字
9 分钟
2026寒假集训个人训练赛第十七场
2026-02-12
统计加载中...

A. 珂朵莉与数字#

可以二分答案,但是小心爆 long long,我就这么 wa 的……

#include <iostream>
using namespace std;
typedef long long LL;
LL n, p;
LL check(LL mid) {
__int128_t res = 1;
for (int i = 0; i < p; ++i) {
res *= mid;
if (res > n) return false;
}
return true;
}
int main() {
ios::sync_with_stdio(0);
cin.tie(0), cout.tie(0);
int T;
cin >> T;
while (T--) {
cin >> n >> p;
LL l = 0, r = n;
while (l < r) {
LL mid = l + r + 1 >> 1;
if (check(mid)) l = mid;
else r = mid - 1;
}
cout << l << endl;
}
return 0;
}

B. 珂朵莉与序列#

排个序,这样就可以把前面的和后面的拆开去绝对值,然后维护一个前缀和和后缀和即可 O(1)O(1) 得出一个位置的答案。

#include <iostream>
#include <algorithm>
using namespace std;
typedef long long LL;
const int N = 100010;
pair<LL, LL> a[N];
LL pre[N], suf[N], res[N];
int main() {
ios::sync_with_stdio(0);
cin.tie(0), cout.tie(0);
int n;
cin >> n;
for (int i = 1; i <= n; ++i) cin >> a[i].first, a[i].second = i;
sort(a + 1, a + n + 1);
for (int i = n; i; --i) suf[i] = suf[i + 1] + a[i].first;
for (int i = 1; i <= n; ++i) {
pre[i] = pre[i - 1] + a[i].first;
res[a[i].second] = a[i].first * i - pre[i] + suf[i] - a[i].first * (n - i + 1);
}
for (int i = 1; i <= n; ++i) cout << res[i] << ' ';
cout << endl;
return 0;
}

C. 珂朵莉与字符串#

线性 DP,维护 fi,jf_{i, j} 表示 S 的前 i 位配对了 chtholly 中的前 j 个的方案数,根据当前位的 SiS_i 考虑状态转移。很可恶的一点是这个题会爆 long long,所以我用 Python 重写了一遍成功过了。

s = input()
n = len(s)
f = [[1, 0, 0, 0, 0, 0, 0, 0, 0]]
for i in range(1, n + 1):
c = s[i - 1]
f.append(f[-1].copy())
if c == 'c':
f[i][1] += f[i - 1][0]
elif c == 'h':
f[i][2] += f[i - 1][1]
f[i][4] += f[i - 1][3]
elif c == 't':
f[i][3] += f[i - 1][2]
elif c == 'o':
f[i][5] += f[i - 1][4]
elif c == 'l':
f[i][6] += f[i - 1][5]
f[i][7] += f[i - 1][6]
elif c == 'y':
f[i][8] += f[i - 1][7]
print(f[n][8])

D. 珂朵莉与面积#

数学题,直接用公式算就行了,方法应该不唯一。就是两个三角形 + 扇形的面积做差或者求和。我这里三角形面积就用了 ×2\frac{\text{底} \times \text{高}}{2},扇形用了 12αr2\frac{1}{2}\alpha r^2.

#include <iostream>
#include <cmath>
#include <iomanip>
#define PI 3.141592653589793
using namespace std;
double work(double a) {
double t = acos(a);
if (t > PI / 2) t = PI - t;
return PI / 2 - t + fabs(sin(t) * cos(t));
}
int sign(double n) {
if (fabs(n) < 1e-7) return 0;
else if (n > 0) return 1;
else return -1;
}
int main() {
ios::sync_with_stdio(0);
cin.tie(0), cout.tie(0);
double l, r;
cin >> l >> r;
cout << fixed << setprecision(3) << fabs(work(l) * sign(l) - work(r) * sign(r)) << endl;
return 0;
}

E. 最大数#

直接线段树即可,或者用无旋 Treap 也可以做。

#include <iostream>
using namespace std;
typedef long long LL;
const int N = 200010;
LL tr[N * 4], D;
int n;
void pushup(int u) {
tr[u] = max(tr[u << 1], tr[u << 1 | 1]);
}
void modify(int u, int l, int r, int p, LL v) {
if (l == r) tr[u] += v;
else {
int mid = l + r >> 1;
if (p <= mid) modify(u << 1, l, mid, p, v);
else modify(u << 1 | 1, mid + 1, r, p, v);
pushup(u);
}
}
LL query(int u, int l, int r, int ql, int qr) {
if (ql <= l && r <= qr) return tr[u];
else {
int mid = l + r >> 1;
LL res = 0;
if (ql <= mid) res = query(u << 1, l, mid, ql, qr);
if (qr > mid) res = max(res, query(u << 1 | 1, mid + 1, r, ql, qr));
return res;
}
}
int main() {
ios::sync_with_stdio(0);
cin.tie(0), cout.tie(0);
cin >> n >> D;
LL t = 0;
int m = 0;
for (int i = 1; i <= n; ++i) {
char op;
LL val;
cin >> op >> val;
if (op == 'A') {
modify(1, 1, n, ++m, (val + t) % D);
}
else {
cout << (t = query(1, 1, n, m - val + 1, m)) << endl;
}
}
return 0;
}

F. Cable master#

又是一道经典的模板题。答案满足单调性,二分答案即可。

#include <iostream>
#include <algorithm>
#include <iomanip>
using namespace std;
typedef long long LL;
const int N = 10010;
LL a[N];
int n, k;
LL get() {
static string s;
cin >> s;
int idx = s.find('.');
if (idx == EOF) return stoi(s);
else return stoi(s.substr(0, idx) + s.substr(idx + 1));
}
bool check(int mid) {
LL cnt = 0;
for (int i = 1; i <= n; ++i) cnt += a[i] / mid;
return cnt >= k;
}
int main() {
ios::sync_with_stdio(0);
cin.tie(0), cout.tie(0);
cin >> n >> k;
for (int i = 1; i <= n; ++i) {
a[i] = get();
}
int l = 0, r = 10000000;
while (l < r) {
int mid = l + r + 1 >> 1;
if (check(mid)) l = mid;
else r = mid - 1;
}
cout << l / 100 << '.' << setw(2) << setfill('0') << l % 100 << endl;
return 0;
}

G. Splitting the Field【Normal】#

考虑到分出的两块不可能重叠,那么直接分别按一个维度排序,枚举分割点对所有可能的答案取 min 即可,排序后预处理前缀、后缀的 max 和 min 即可 O(n)O(n) 枚举答案。

#include <iostream>
#include <algorithm>
using namespace std;
typedef long long LL;
const int N = 50010;
pair<LL, LL> a[N];
LL pre_mx[N], pre_mn[N], suf_mx[N], suf_mn[N];
LL res;
int n;
void work() {
sort(a + 1, a + n + 1);
pre_mn[0] = suf_mn[n + 1] = 1000000001;
for (int i = 1; i <= n; ++i) {
pre_mx[i] = max(pre_mx[i - 1], a[i].second);
pre_mn[i] = min(pre_mn[i - 1], a[i].second);
}
for (int i = n; i; --i) {
suf_mx[i] = max(suf_mx[i + 1], a[i].second);
suf_mn[i] = min(suf_mn[i + 1], a[i].second);
}
for (int i = 2; i <= n; ++i) {
if (a[i - 1].first != a[i].first) {
res = min(res, (pre_mx[i - 1] - pre_mn[i - 1]) * (a[i - 1].first - a[1].first) + (suf_mx[i] - suf_mn[i]) * (a[n].first - a[i].first));
}
}
}
int main() {
ios::sync_with_stdio(0);
cin.tie(0), cout.tie(0);
cin >> n;
LL mnx = 1000000001, mny = 1000000001, mxx = 0, mxy = 0;
for (int i = 1; i <= n; ++i) {
auto &[x, y] = a[i];
cin >> x >> y;
mnx = min(mnx, x), mny = min(mny, y);
mxx = max(mxx, x), mxy = max(mxy, y);
}
res = (mxx - mnx) * (mxy - mny);
work();
for (int i = 1; i <= n; ++i) {
swap(a[i].first, a[i].second);
}
work();
cout << (mxx - mnx) * (mxy - mny) - res << endl;
return 0;
}

H. Dishwashing#

考虑到如果一个前缀已经不合法了,往后加元素一定也不可能合法,所以答案具有单调性。另外检查一段前缀是否合法很好写,所以可以考虑二分答案。

想要检查一个前缀是否合法,只需要模拟一遍他的流程。Bessie 放出的所有栈从栈顶到栈底一定单调递增,从左到右的所有栈中的元素一定单调递增,否则 Elsie 不可能取出一个有序的序列。拿到一个新的盘子时,检查能不能直接被取走,如果不能就二分到第一个比他大的栈放到栈顶即可。每次放完都贪心的让 Elsie 尝试取。最后如果取完了就是可行,否则不可行。

#include <iostream>
#include <stack>
#include <algorithm>
using namespace std;
const int N = 100010;
int a[N], b[N], n;
stack<int> q[N];
bool check(int m) {
int j = 1, k = 1, len = 0;
for (int i = 1; i <= m; ++i) b[i] = a[i];
sort(b + 1, b + m + 1);
for (int i = 1; i <= m && j <= m; ++i) {
if (a[i] == b[j]) j++;
else {
int l = k, r = len + 1;
while (l < r) {
int mid = l + r >> 1;
if (q[mid].top() > a[i]) r = mid;
else l = mid + 1;
}
if (l == len + 1) q[++len].emplace(a[i]);
else q[l].emplace(a[i]);
}
while (j <= m && k <= len && b[j] == q[k].top()) {
q[k].pop();
j++;
if (q[k].empty()) k++;
}
}
for (int i = 1; i <= m; ++i) while (!q[i].empty()) q[i].pop();
return j == m + 1;
}
int main() {
ios::sync_with_stdio(0);
cin.tie(0), cout.tie(0);
cin >> n;
for (int i = 1; i <= n; ++i) cin >> a[i];
int l = 1, r = n;
while (l < r) {
int mid = l + r + 1 >> 1;
if (check(mid)) l = mid;
else r = mid - 1;
}
cout << l << endl;
return 0;
}
2026寒假集训个人训练赛第十七场
https://starlab.top/posts/2026wp17/
作者
Star
发布于
2026-02-12
许可协议
CC BY-NC-SA 4.0

部分信息可能已经过时