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;
}

T3 蛋糕

T4 字符替换

posted @ 2025-07-25 14:10  Zctf1088  阅读(22)  评论(0)    收藏  举报