Codeforces Round 975 (Div. 2)

A

int T, n, a[105], dp[105][2];

signed main(void) {
	for (read(T); T; T--) {
		read(n); int mx = 0, id = 0;
		for (int i = 1; i <= n; i++) {
			read(a[i]);
			if (a[i] > mx) {
				mx = a[i];
				id = i % 2;
			} else if (a[i] == mx) chkmax(id, i % 2);
		}
		writeln(mx + (id + n) / 2);
	}
	//fwrite(pf, 1, o1 - pf, stdout);
	return 0;
}

B

模拟就行,一开始看错题目了妈的

const int N = 1e5 + 5;
int T, n, q, x[N];

inline bool check(int x, ll k) {
	return 1ll * n * (n - 1) / 2 - 1ll * x * (x + 1) / 2 >= k;
}

map <ll, ll> h; 

signed main(void) {
	for (read(T); T; T--) {
		read(n); read(q);
		for (int i = 1; i <= n; i++) read(x[i]);
		for (int i = 1; i < n; i++) {
			h[1ll * i * (n - i)] += x[i + 1] - x[i] - 1;
			h[1ll * i * (n - i + 1) - 1]++;
//			h[1ll * (i + 1) * (n - i) - 1]++;
		}
		h[n - 1]++;
		while (q--) {
			ll k; read(k);
			if (h.find(k) == h.end()) { writeln(0, ' '); }
			else writeln(h[k], ' ');
		}
		puts("");
		h.clear();
	}
	//fwrite(pf, 1, o1 - pf, stdout);
	return 0;
}

C

O(n) 判断,满足即是最大值。

const int N = 2e5 + 5;
int T, n; ll a[N], k;

signed main(void) {
	for (read(T); T; T--) {
		read(n), read(k); ll tot = 0, mx = 0;
		for (int i = 1; i <= n; i++) read(a[i]), tot += a[i], chkmax(mx, a[i]);
		ll ans = 1;
		for (ll i = n; i >= 1; i--) {
			ll j = max((tot + i - 1) / i, mx);
			if (i * j - tot <= k) { ans = i; break; }
		}
		writeln(ans);
	}
	//fwrite(pf, 1, o1 - pf, stdout);
	return 0;
}

D

本质是区间的交的长度。中间要判断一下是否满足连续否则为0

const int N = 2e5 + 5;
int T, n, a[N], pre[N], suf[N], p1[N], p2[N];

signed main(void) {
	for (read(T); T; T--) {
		read(n);
		for (int i = 1; i <= n; i++) read(a[i]);
		int mx = 1, mn = n;
		for (int i = 1; i <= n; i++) {
			p2[i] = a[i] + i - 1;
			p1[i] = i - a[i] + 1;
			chkmax(mx, p1[i]);
			chkmin(mn, p2[i]);
		}
		pre[0] = n + 1;
		for (int i = 1; i <= n; i++) pre[i] = min(pre[i - 1], p2[i]);
		suf[n + 1] = 0;
		for (int i = n; i >= 1; i--) suf[i] = max(suf[i + 1], p1[i]);
		bool f = true;
		for (int i = 1; i <= n; i++) {
			p2[i] = a[i] + i - 1;
			p1[i] = i + 1 - a[i];
			if (pre[max(p1[i] - 1, 0)] < i || suf[min(p2[i] + 1, n + 1)] > i) f = false; 
		}
		if (f) writeln(max(mn - mx + 1, 0));
		else writeln(0);
	}
	//fwrite(pf, 1, o1 - pf, stdout);
	return 0;
}

E

差分,找标记最多的深度,然后开始砍

const int N = 5e5 + 5;
int T, n; vector <int> G[N];
int dep[N], d[N], h[N], mx = 0, ans = 0, ret = 0;

inline void dfs(int u, int f) {
	dep[u] = dep[f] + 1;
	d[u] = dep[u];
	for (auto v : G[u]) {
		if (f == v) continue;
		dfs(v, u); chkmax(d[u], d[v]);
//		writeln(d[v], ' '), writeln(dep[v]);
		h[dep[v]]++; h[d[v] + 1]--;
	}
}

inline void dfs2(int u, int f) {
	for (auto v : G[u]) {
		if (f == v) continue;
		dfs2(v, u); if (d[v] < ans || dep[v] > ans) ++ret;
	}
}

signed main(void) {
	for (read(T); T; T--) {
		read(n);  h[1] = 0; mx = 0; ans = 0; ret = 0;
		for (int i = 1; i <= n; i++) G[i].clear();
		for (int i = 1, u, v; i < n; i++) {
			read(u), read(v);
			G[u].push_back(v);
			G[v].push_back(u);
			h[i + 1] = dep[i + 1] = d[i + 1] = 0;
		}
		
		dfs(1, 0);
		for (int i = 2; i <= n; i++) h[i] += h[i - 1];
		
		for (int i = 1; i <= n; i++) if (h[i] > mx) mx = h[i], ans = i;
		dfs2(1, 0);
		writeln(ret);
	}
	//fwrite(pf, 1, o1 - pf, stdout);
	return 0;
}

F

ddp题解,就是 f[pos][o][l][r] 表示线段树上pos位置的区间是否选出最大值,以及左右端点有没有被去到时的最大值。然后用线段树维护依次取某个值为最小值的时候dp的最优解。

const int N = 2e5 + 5;
int T, n, a[N], f[N << 2][2][2][2];
inline int getmax(int pos) { return max(max(f[pos][1][0][0], f[pos][1][1][0]), max(f[pos][1][1][1], f[pos][1][0][1])); }
inline void update(int pos, int idx) {
	for (int i = 0; i < 2; i++)
	for (int j = 0; j < 2; j++)
	for (int k = 0; k < 2; k++) f[pos][i][j][k] = -1e9;
	f[pos][0][0][0] = 0;
	if (a[idx] < 0) return;
	f[pos][0][1][1] = 1;
	f[pos][1][1][1] = a[idx] + 1;
}

inline void pushup(int pos) {
	for (int i = 0; i < 2; i++)
	for (int j = 0; j < 2; j++)
	for (int k = 0; k < 2; k++) f[pos][i][j][k] = -1e9;
	
	for (int a = 0; a < 2; a++)
	for (int b = 0; a + b < 2; b++)
	for (int i = 0; i < 2; i++)
	for (int j = 0; j < 2; j++)
	for (int x = 0; x + j < 2; x++)
	for (int y = 0; y < 2; y++)
		chkmax(f[pos][a + b][i][y], f[pos << 1][a][i][j] + f[pos << 1 | 1][b][x][y]);
}

inline void build(int pos, int l, int r) {
	if (l == r) { update(pos, l); return; }
	int mid = l + r >> 1;
	build(pos << 1, l, mid);
	build(pos << 1 | 1, mid + 1, r);
	pushup(pos);
}

inline void modify(int pos, int l, int r, int x) {
	if (l == r) { update(pos, l); return; }
	int mid = l + r >> 1;
	if (x <= mid) modify(pos << 1, l, mid, x);
	else modify(pos << 1 | 1, mid + 1, r, x);
	pushup(pos);
}

vector <pii> vec;

signed main(void) {
	for (read(T); T; T--) {
		read(n); vec.clear();
		for (int i = 1; i <= n; i++)
			read(a[i]), vec.push_back(Mp(a[i], i));
		build(1, 1, n); sort(vec.begin(), vec.end());
		int ret = 0;
		for (auto u : vec) {
			int x = u.first, y = u.second;
			chkmax(ret, x + getmax(1));
			a[y] = -1;
			modify(1, 1, n, y);
		}
		writeln(ret);
	}
	//fwrite(pf, 1, o1 - pf, stdout);
	return 0;
}
posted @   EternalEpic  阅读(467)  评论(3编辑  收藏  举报
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
点击右上角即可分享
微信分享提示