ABC390 - 魔怔记

复盘

A,把所有可能的答案列举出来,最后字符串判等即可……

B,没什么难度,码完交上去 WA 3 个点。

不知道是不是精度问题,开了 long double,WA 1 个点。

调调调,发现 eps 设大了,改成 1012 过了。

C 算什么东西,随便写写就过了。

D,一眼看到数据范围是个搜索,写出来 T 了,调了一下发现常数大了一点,卡卡常过了。

E,本来打了一个无敌大背包,然后柿子推错了,改成了二分答案套背包,改改就一遍过了。

F,一眼扫描线,并想都没想就上线段树(线段树题做魔怔了导致的),然后调到了结束遗憾离场。


后面想了想 F,发现好像没必要上线段树(嗯又不魔怔了),改了下不仅代码长度少 40 行还少了只 log

题解

A

堂题,不说了。

B

堂题,但是注意精度。

C

堂题,不说了。

D

dfs + 剪枝。

首先,暴力搜索 a 中哪两个数相加显然不够优秀,会 T 飞,我们考虑换一种搜索方式。

对于每一个数 ai,找到一个 bj,将 ai 加到 bj 上,最后统计 b 的异或和也可以达到与题目相符的同样的结果(b 数组可以看作我们新定义的初始为空的数组)。

但是他仍然 T 飞了。

冷静分析,发现每一次搜索没必要搜 n 个位置,只需要搜到 b 中第一个为 0 的位置即可,这样也可以做到不重不漏。

不过同样的优化我们也需要放在统计 b 的异或和的循环里。

卡卡常就能过了。

#include <bits/stdc++.h>
#define int long long
#define pii pair<int, int>
#define FRE(x) freopen(x ".in", "r", stdin), freopen(x ".out", "w", stdout)
#define ALL(x) x.begin(), x.end()
using namespace std;

int _test_ = 1;

const int N = 14;

int n, a[N], b[N], ans;
unordered_map<int, int> mp; // 补药用 map,会 T

void dfs(int u) {
	if (u == n + 1) {
		int g = 0;
		for (int i = 1; i <= n; i++) {
  			if (b[i] == 0) break; // 如果当前位置为 0 直接跳出循环
			g ^= b[i];
		}
		if (mp[g] == 0) // 又多了一个答案
			ans++, mp[g] = 1;
	}
	bool zero = false;
	for (int i = 1; i <= n; i++) {
		zero = b[i] == 0;
		b[i] += a[u];
		dfs(u + 1);
		b[i] -= a[u];
		if (zero) break; // 如果当前位置为 0 直接跳出循环
	}
}

void init() {}

void clear() {}

void solve() {
	cin >> n;
	for (int i = 1; i <= n; i++) {
		cin >> a[i];
	}
	dfs(1);
	cout << ans;
}

signed main() {
	ios::sync_with_stdio(0);
	cin.tie(0), cout.tie(0);
//	cin >> _test_;
	init();
	while (_test_--) {
		clear();
		solve();
	}
	return 0;
}

E

二分 + 背包

我们先不考虑哪一种维生素摄入量最少,只二分摄入量的最小值,其他的事情交给 check。

在 check 里,对每一种维生素食品都做一次背包。

接着我们找到最小的产生的卡路里值,使得该种维生素摄取量 >mid(如果没有显然就不满足条件),求和统计一下。

因为每种食物都只会涉及到一种维生素,所以每种食品只会被考虑一遍,那么最后统计到的和就是使得每种维生素摄取量的最小值 >mid 的最小卡路里消耗量,与 X 比较一下即可。

注意:

  • 二分的起点是 l=0,r=1018,不要弄错了。
  • 背包是 01 背包,不要打成别的背包了。
#include <bits/stdc++.h>
#define int long long
#define pii pair<int, int>
#define FRE(x) freopen(x ".in", "r", stdin), freopen(x ".out", "w", stdout)
#define ALL(x) x.begin(), x.end()
using namespace std;

int _test_ = 1;

const int N = 5005, X = 5005;

struct node {
	int A[3];
} a[N];
int n, t;
int dp[N];

bool check(int x) {
	int ans = 0;
	for (int op = 1; op <= 3; op++) {
		memset(dp, 0, sizeof(dp));
		for (int i = 1; i <= n; i++) {
			if (a[i].A[0] != op) continue;
			for (int j = N - 5; j >= a[i].A[2]; j--) {
				dp[j] = max(dp[j], dp[j - a[i].A[2]] + a[i].A[1]);
			}
		}
		if (dp[N - 5] < x) return false;
		for (int i = 1; i <= N - 5; i++) {
			if (dp[i] < x) continue;
			ans += i;
			break;
		}
	}
	return ans <= t;
}

void init() {}

void clear() {}

void solve() {
	cin >> n >> t;
	for (int i = 1; i <= n; i++) {
		cin >> a[i].A[0] >> a[i].A[1] >> a[i].A[2];
	}
	int l = 0, r = 1e18, ans = 0;
	while (l <= r) {
		int mid = (l + r) >> 1;
		if (check(mid)) {
			ans = mid;
			l = mid + 1;
		} else {
			r = mid - 1;
		}
	}
	cout << ans;
}

signed main() {
	ios::sync_with_stdio(0);
	cin.tie(0), cout.tie(0);
//	cin >> _test_;
	init();
	while (_test_--) {
		clear();
		solve();
	}
	return 0;
}

F

枚举 R,找到所有 L 的结果之和。

记一个 l 数组,lai 就代表上一次 ai 出现的下标。

会影响到 aR 的一共只有三个数,aR1aRaR+1,分别计算以一下。

值得注意的是,如果 aR1aR+1 都存在但是 aR 不存在,添加上 aR 之后区间切割就可以少切一刀了。

维护维护就行了。

#include <bits/stdc++.h>
 #define int long long
#define pii pair<int, int>
#define FRE(x) freopen(x ".in", "r", stdin), freopen(x ".out", "w", stdout)
#define ALL(x) x.begin(), x.end()
using namespace std;

int _test_ = 1;

const int N = 3e5 + 5;
int n, a[N], lst[N];

void init() {}

void clear() {}

void solve() {
	cin >> n;
	for (int i = 1; i <= n; i++) {
		cin >> a[i];
	}
	int ans = 0, now = 0;
	for (int i = 1; i <= n; i++) {
		int _r = lst[a[i] - 1], r = lst[a[i]], r_ = lst[a[i] + 1];
		now += i - r;
		if (_r > r) now += r - _r;
		if (r_ > r) now += r - r_;
		lst[a[i]] = i;
		ans += now;
	}
	cout << ans;
}

signed main() {
	ios::sync_with_stdio(0);
	cin.tie(0), cout.tie(0);
//	cin >> _test_;
	init();
	while (_test_--) {
		clear();
		solve();
	}
	return 0;
}
posted @   Archippus  阅读(11)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· 清华大学推出第四讲使用 DeepSeek + DeepResearch 让科研像聊天一样简单!
· 实操Deepseek接入个人知识库
· CSnakes vs Python.NET:高效嵌入与灵活互通的跨语言方案对比
· Plotly.NET 一个为 .NET 打造的强大开源交互式图表库
点击右上角即可分享
微信分享提示