Codeforces Round 899 (Div. 2)更新ing

A. Increasing Sequence

题意
给你一个数组\(a\),需要构造出一个新的数组,大小相同,对应位置的数不一样,新数组且保持递增,求新数组\(b\)\(b_n\)的最小值

线索1
显然贪心模拟,从1开始模拟就行
点击查看代码
void solve() {
	int n;
	cin >> n;
	vector<int> a(n + 1, 0);
	rep(i, 1, n) cin >> a[i];
	int cnt = 0;
	rep(i, 1, n) {
		cnt++;
		if(a[i] != cnt) continue;
		cnt++;
	}
	cout << cnt << "\n";
}

B. Sets and Union

题意
给你\(n\)个集合,让你在其中选若干集合,这些集合的并集,不能跟所有集合的并集大小相同,问该并集最大是多少?
(!!!
线索

线索1
既然不会等于所有集合的并集大小,至少要缺少一个元素。
线索2
看看数据范围
线索3
数据范围很小,我们直接枚举缺失的元素就行。
点击查看代码
int n, a[55][55], vis[55], siz[55];
void solve() {
	memset(a, 0, sizeof a);
	cin >> n;
	map<int, int> mp;
	rep(i, 1, n) {
		cin >> siz[i];
		rep(j, 1, siz[i]) {
			int x;
			cin >> x;
			mp[x]++;
			a[i][x]++;
		}
	}
	int mx = 0;
	rep(i, 1, 50) {
		if(!mp[i]) continue;
		int cnt = 0;
		memset(vis, 0, sizeof vis);
		rep(j, 1, n) {
			if(a[j][i]) continue;
			rep(k, 1, 50) {
				if(a[j][k]) vis[k] = 1;
			}
			
		}
		rep(k, 1, 50) cnt += vis[k];
		mx = max(mx, cnt);
	}
	cout << mx << "\n";
}

C. Card Game

题意
给你一个大小为\(n\)的数组,可以任意拿掉某个位置的数,拿完以后整个数组索引重新计算,拿掉奇数位置,累加该位置对应的数的得分,拿掉偶数位置不加分。

线索

线索1
拿掉一个元素以后,后面的元素位置都会发生变化,该位置后面的数是否都能随便取。
线索2
如果在某个位置拿掉元素,该元素后面的元素都可以随便取最优的,如果后面的某个数可以在改变之前取,那就在改变之前取,递归的想,归纳法证明。处理后缀最大值,枚举拿掉哪一个数即可。
点击查看代码
void solve() {
	int n;
	cin >> n;
	vector<int> a(n + 1);
	rep(i, 1, n) cin >> a[i];
	int suf = 0, mx = 0;
	for(int i = n; i >= 1; --i) {
		if(i & 1) mx = max(mx, a[i] + suf);
		else mx = max(mx, suf);
		suf += max(0ll, a[i]);
	}
	cout << mx << "\n";
}

D. Tree XOR

题意
给你一棵树,每个节点都有权值\(a_i\),每次可以选择一个节点\(u\),和随意一个值\(w\),将这个节点,包括他的子树,都变成\(a_i\) ^ \(w\),求出每个点作为顶点的最小操作次数。

线索1

线索2

线索3

点击查看代码
const int N = 2e5 + 10;
 
int cnt, head[N];
struct node {
	int to, nex;
}e[N << 1];
void add(int u, int v) {
	e[++cnt].nex = head[u], e[cnt].to = v, head[u] = cnt;
}
int n, a[N], ok[N], f[N], siz[N];
void dfs1(int u, int fa) {
	siz[u] = 1;
	for(int i = head[u]; i; i = e[i].nex) {
		int v = e[i].to;
		if(v == fa) continue;
		dfs1(v, u);
		siz[u] += siz[v];
		f[1] += (a[u] ^ a[v]) * siz[v];
	}
}
void dfs2(int u, int fa) {
	for(int i = head[u]; i; i = e[i].nex) {
		int v = e[i].to;
		if(v == fa) continue;
		f[v] = f[u] - siz[v] * (a[u] ^ a[v]) + (n - siz[v]) * (a[u] ^ a[v]);
		dfs2(v, u);
	} 
}
void solve() {
	cnt = 0;
	rep(i, 0, n) head[i] = 0;
	cin >> n;
	rep(i, 1, n) f[i] = 0;
	rep(i, 1, n) cin >> a[i];
	rep(i, 2, n) {
		int u, v;
		cin >> u >> v;
		add(u, v), add(v, u);
	}
	dfs1(1, 1);
	dfs2(1, 1);
	rep(i, 1, n) cout << f[i] << " \n"[i == n];
 
	//cout << val << "\n";
}

posted on 2023-09-21 11:24  C2-103  阅读(52)  评论(0)    收藏  举报

导航