CF670div.2

A Subset Mex

题意:将给定集合分成 \(A,B\) 两份,\(mex(S)\) 表示集合 \(S\) 中未出现的最小非负整数,求 \(\max{mex(A)+mex(B)}\)

  \(v_i\) 表示 \(i(0\le i\le100)\) 的个数,所有只出现一次的放入 \(B\) 中,\(mex(A)\) 为满足 \(v_i\le1\) 的最小的 \(i\)\(mex(B)\) 为满足 \(v_i=0\) 的最小的 \(i\)

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
using namespace std;

#define debug(x) cout << #x << " is " << x << endl
#define inc(i, a, b) for (int i = a; i <= b; ++i)
typedef long long ll;
const int INF = 0x3f3f3f3f, N = 105;

int t, n;
int v[N];

int main() 
{
	scanf("%d", &t);
	while (t--) {
		scanf("%d", &n);
		memset(v, 0, sizeof(v));
		for (int i = 1; i <= n; ++i) {
			int x;
			scanf("%d", &x);
			v[x]++;
		}
		int ans = 0;
		for (int i = 0; v[i] >= 2; ++i, ++ans);
		for (int i = 0; v[i] >= 1; ++i, ++ans);
		printf("%d\n", ans);
	}
    return 0;
}

B Maximum Product

题意:给出一个长度为 \(n(5\le n\le10^5)\) 的数组,任选 5 个不同的数求最大值。

  经典问题atcoder abc173e的一个特例。直接排序,答案只有 3 种情况:不取负数、取 1 对负数和取 2 对负数。

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
using namespace std;

#define debug(x) cout << #x << " is " << x << endl
#define inc(i, a, b) for (int i = a; i <= b; ++i)
typedef long long ll;
const int INF = 0x3f3f3f3f, N = 1e5 + 5;

int t, n;
ll a[N];
ll ans1, ans2, ans3;

int main() 
{
	scanf("%d", &t);
	while (t--) {
		scanf("%d", &n);
		for (int i = 1; i <= n; ++i) scanf("%lld", &a[i]);
		sort(a + 1, a + n + 1);
		ans1 = a[n] * a[n-1] * a[n-2] * a[n-3] * a[n-4];
		ans2 = a[n] * a[n-1] * a[n-2] * a[1] * a[2];
		ans3 = a[n] * a[1] * a[2] * a[3] * a[4];
		printf("%lld\n", max(ans1, max(ans2, ans3)));
	}
    return 0;
}

题意:在树中删一条边加一条边(可以是同一条边)使得质心唯一,其中质心:删掉该点和引出的边后,剩下的图中最大连通块最小的点。

  以结点 1 作为根结点,利用 dfs 找出一个最后一个质心 rt,若有两个质心其父结点 frt 也必为质心。如果 rt 不为 1,删除 frt 子树是叶子结点的点并连接至 rt,rt 成为唯一的质心。

  证明:易知 frt 的子树结点个数为 \(\frac{n}{2}\),删除连接后,rt 的最大连通块结点个数为 \(\frac{n}{2}-1\) 而 frt 的最大连通块结点个数为 \(\frac{n}{2}+1\)

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <vector>
using namespace std;

#define debug(x) cout << #x << " is " << x << endl
#define inc(i, a, b) for (int i = a; i <= b; ++i)
typedef long long ll;
const int INF = 0x3f3f3f3f, N = 1e5 + 5;

vector<int> e[N];
int t, n, rt, frt, p1, p2;
int sz[N];

void dfs(int x, int fa) {
	int mx = 0;
	sz[x] = 1;
	for (auto i : e[x]) {
		if (i != fa) {
			dfs(i, x);
			sz[x] += sz[i];
			mx = max(mx, sz[i]);
		}
	}
	if (sz[x] * 2 >= n && mx * 2 < n)
		rt = x, frt = fa;
}

void dfs2(int x, int fa) {
	if (e[x].size() == 1) {
		p1 = x, p2 = fa;
	}
	for (auto i : e[x]) {
		if (i != fa) dfs2(i, x);
	}
}

int main() 
{
	scanf("%d", &t);
	while (t--) {
		scanf("%d", &n);
		for (int i = 1; i <= n; ++i) e[i].clear();
		for (int i = 1; i <= n - 1; ++i) {
			int x, y;
			scanf("%d%d", &x, &y);
			e[x].push_back(y);
			e[y].push_back(x);
		}
		dfs(1, 0);
		if (rt == 1) {
			printf("%d %d\n", 1, e[1][0]);
			printf("%d %d\n", 1, e[1][0]);
		}
		else {
			dfs2(frt, rt);
			printf("%d %d\n", p1, p2);
			printf("%d %d\n", p1, rt);
		}
	}
    return 0;
}
posted @ 2020-09-13 23:45  2inf  阅读(114)  评论(0)    收藏  举报