2025CSP-S模拟赛26 比赛总结
2025CSP-S模拟赛26
| T1 | T2 | T3 | T4 |
|---|---|---|---|
| 100 AC | - | 0 TLE | 0 RE |
排名:10/24;总分:100
T1 集合
双指针扫一遍,权值线段树维护区间最大子段和即可。
#include <bits/stdc++.h>
#define il inline
#define int long long
using namespace std;
const int bufsz = 1 << 20;
char ibuf[bufsz], *p1 = ibuf, *p2 = ibuf;
#define getchar() (p1 == p2 && (p2 = (p1 = ibuf) + fread(ibuf, 1, bufsz, stdin), p1 == p2) ? EOF : *p1++)
il int read() {
int x = 0; char ch = getchar(); bool t = 0;
while (ch < '0' || ch > '9') {t ^= ch == '-'; ch = getchar();}
while (ch >= '0' && ch <= '9') {x = (x << 1) + (x << 3) + (ch ^ 48); ch = getchar();}
return t ? -x : x;
}
const int INF = 0x3f3f3f3f3f3f3f3f;
const int N = 2e5 + 10;
int n, kk, a[N];
struct node {
int l, r, mx, s, lmx, rmx, val;
} tree[4 * N];
#define lc p << 1
#define rc p << 1 |1
il void build(int p, int l, int r) {
tree[p].l = l, tree[p].r = r;
if (l == r) return;
int mid = l + r >> 1;
build(lc, l, mid), build(rc, mid + 1, r);
}
il void pushup(int p) {
tree[p].s = tree[lc].s + tree[rc].s;
tree[p].lmx = max(tree[lc].lmx, (tree[lc].s == tree[lc].r - tree[lc].l + 1 ? tree[lc].s + tree[rc].lmx : -INF));
tree[p].rmx = max(tree[rc].rmx, (tree[rc].s == tree[rc].r - tree[rc].l + 1 ? tree[rc].s + tree[lc].rmx : -INF));
tree[p].mx = max(tree[lc].rmx + tree[rc].lmx, max(tree[lc].mx, tree[rc].mx));
}
il void update(int p, int x, int v) {
if (tree[p].l == tree[p].r) {
tree[p].val += v;
tree[p].s = tree[p].mx = tree[p].lmx = tree[p].rmx = (tree[p].val >= 1);
return;
}
int mid = tree[p].l + tree[p].r >> 1;
if (x <= mid) update(lc, x, v);
else update(rc, x, v);
pushup(p);
}
signed main() {
n = read(), kk = read();
for (int i = 1; i <= n; i++) a[i] = read();
build(1, 1, n);
int l = 1, r = 1, lstl = 0;
int cnt = 0;
for (; l <= n; l++) {
for (; r <= n && tree[1].mx <= kk; r++) {
update(1, a[r], 1);
}
if (tree[1].mx > kk) {
cnt += (l - lstl) * (n - (r - 1) + 1);
lstl = l;
}
update(1, a[l], -1);
}
int ans = n * (n + 1) / 2 - cnt;
printf("%lld\n", ans);
return 0;
}
T2 差后队列
此题被题解称为签到题,确实不难。但是由于打完比赛当天脑子不好,改了一下午一晚上没看懂,第二天早上随意做 50 min 切掉。
这篇写的挺好,看吧。
#include <bits/stdc++.h>
#define il inline
#define int long long
using namespace std;
const int bufsz = 1 << 20;
char ibuf[bufsz], *p1 = ibuf, *p2 = ibuf;
#define getchar() (p1 == p2 && (p2 = (p1 = ibuf) + fread(ibuf, 1, bufsz, stdin), p1 == p2) ? EOF : *p1++)
il int read() {
int x = 0; char ch = getchar(); bool t = 0;
while (ch < '0' || ch > '9') {t ^= ch == '-'; ch = getchar();}
while (ch >= '0' && ch <= '9') {x = (x << 1) + (x << 3) + (ch ^ 48); ch = getchar();}
return t ? -x : x;
}
const int INF = 0x3f3f3f3f3f3f3f3f;
const int MOD = 998244353;
const int N = 1e6 + 10;
int n;
il int fpow(int a, int x) {
a %= MOD;
int ans = 1;
while (x) {
if (x & 1) ans = ans * a % MOD;
a = a * a % MOD;
x >>= 1;
}
return ans;
}
il int ny(int x) {
return fpow(x, MOD - 2);
}
int op[N], a[N], t[N], c[N];
int ans[N];
vector<int> num[N];
signed main() {
n = read();
int sum = 0, cnt = 0, mx = 0, mxid = 0;
for (int i = 1; i <= n; i++) {
op[i] = read();
if (op[i] == 0) {
a[i] = read();
sum = (sum + a[i]) % MOD;
cnt++;
if (a[i] > mx) {
t[mxid] = i;
num[i].push_back(mxid);
mx = a[i], mxid = i;
} else {
t[i] = i;
num[i].push_back(i);
}
} else {
if (cnt == 1) {
ans[i] = mx;
ans[mxid] = i;
mx = mxid = sum = cnt = 0;
} else {
ans[i] = (sum - mx) % MOD * ny(cnt - 1) % MOD;
sum = (sum - ans[i]) % MOD;
c[i] = cnt;
cnt--;
}
}
}
int val = 0;
for (int i = n; i >= 1; i--) {
if (op[i] == 1) {
val = (i * ny(c[i] - 1) % MOD + (1 - ny(c[i] - 1)) % MOD * val) % MOD;
}
for (int j : num[i]) ans[j] = val;
}
for (int i = 1; i <= n; i++) {
printf("%lld ", (ans[i] + MOD) % MOD);
}
return 0;
}

浙公网安备 33010602011771号