[赛记] 多校A层冲刺NOIP2024模拟赛05

这场数数

好数(number)100pts

找三个数的和,而且允许 $ \Theta(n^2) $,那么我们可以维护出两个数的和,然后每次顺序遍历找这个数减去前面的某个数在任意两个数的和中有没有出现过,这个也是 $ \Theta(n^2) $ 的;

所以时间复杂度:$ \Theta(n^2) $,如果带 $ \log $ 会过不去,要用桶维护;

点击查看代码
#include <iostream>
#include <cstdio>
using namespace std;
int n;
int a[500005];
int ans;
bool vis[5000005][2];
int main() {
	freopen("number.in", "r", stdin);
	freopen("number.out", "w", stdout);
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	cin >> n;
	for (int i = 1; i <= n; i++) {
		cin >> a[i];
	}
	if (a[1] * 2 < 0) vis[-1 * a[1] * 2][0] = true;
	else vis[a[1] * 2][1] = true;
	for (int i = 2; i <= n; i++) {
		bool vi = false;
		for (int j = 1; j < i; j++) {
			int now = a[i] - a[j];
			if (now < 0) {
				if (vis[-1 * now][0]) {
					vi = true;
					break;
				}
			} else {
				if (vis[now][1]) {
					vi = true;
					break;
				}
			}
		}
		if (vi) ans++;
		for (int j = 1; j <= i; j++) {
			int now = a[i] + a[j];
			if (now < 0) vis[-1 * now][0] = true;
			else vis[now][1] = true;
		}
	}
	cout << ans;
	return 0;
}

SOS字符串(sos)0pts

赛时容斥了3.5h不对,其实不能容斥,因为找不到正好大于等于某个数的,总是会有重复;

所以考虑DP(貌似除了容斥就是DP把);

设 $ f_{i, j, 0/1/2} $ 表示考虑前 $ i $ 位,已经匹配了 $ j $ 个 SOS ,现在匹配到了 SOS 的第一位(1),第二位(2),第三位或者其它字母(0)时的方案数;

转移时正常转移,但是是 $ \Theta(n^2) $ 的;

当我们写出转移方程时,其实会发现对于 $ j \geq 2 $ 的状态,转移都是重复的,所以我们不需要挨个转移,直接统计一下即可;

时间复杂度: $ \Theta(n) $,有常数;

点击查看代码
#include <iostream>
#include <cstdio>
using namespace std;
const long long mod = 1e9 + 7;
long long n;
long long f[1000005][5][5];
int main() {
	freopen("sos.in", "r", stdin);
	freopen("sos.out", "w", stdout);
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	cin >> n;
	if (n < 9) {
		cout << 0;
		return 0;
	}
	if (n == 9) {
		cout << 1;
		return 0;
	}
	f[0][0][0] = 1;
	for (int i = 1; i <= n; i++) {
		for (int j = 0; j <= 2; j++) {
			f[i][j][0] = (f[i - 1][j][0] * 25 % mod + f[i - 1][j][1] * 24 % mod + f[i - 1][j][2] * 25 % mod) % mod;
			if (j) f[i][j][0] = (f[i][j][0] + f[i - 1][j - 1][2]) % mod;
			f[i][j][1] = (f[i - 1][j][0] + f[i - 1][j][1]) % mod;
			f[i][j][2] = f[i - 1][j][1];
		}
		f[i][3][0] = (f[i - 1][3][0] * 26 % mod + f[i - 1][2][2] % mod) % mod;
	}
	cout << f[n][3][0];
	return 0;
}

集训营的气球(balloon)0pts

首先考虑没有修改怎么做,那么我们发现这是一个背包问题,设 $ f_{i, j} $ 表示前 $ i $ 个人,有 $ j $ 个人买了特殊气球的方案数,转移考虑第 $ i $ 个人买不买特殊气球即可;

可以滚动数组;

但是有修改怎么办?

暴力的思路是每次修改重新跑一遍背包,这样时间复杂度显然不对;

那么我们怎么干?有个东西叫做退背包

就是做背包的时候反着做,退背包的时候正着做,然后把运算取反即可;

对于正确性,可以参考Luogu P4141;

所以这里就是先强制撤销这个数,然后在加进来;

最后用一个小容斥,用总方案数减去小于c的方案数;

所以时间复杂度;$ \Theta(nc \log mod) $;

点击查看代码
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const long long mod = 1e9 + 7;
long long ksm(long long a, long long b) {
	long long ans = 1;
	while(b) {
		if (b & 1) ans = ans * a % mod;
		a = a * a % mod;
		b >>= 1;
	}
	return ans;
}
int n, c, q;
int a[1000005], b[1000005];
long long f[1000005], tot;
void w() {
	f[0] = 1;
	tot = 1;
	for (int i = 1; i <= n; i++) {
		for (int j = c - 1; j >= 1; j--) {
			f[j] = (f[j - 1] * a[i] % mod + f[j] * b[i] % mod) % mod;
		}
		f[0] = f[0] * b[i] % mod;
		tot = (tot * (a[i] + b[i]) % mod) % mod;
	}
}
int main() {
	freopen("balloon.in", "r", stdin);
	freopen("balloon.out", "w", stdout);
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	cin >> n >> c;
	for (int i = 1; i <= n; i++) cin >> a[i];
	for (int i = 1; i <= n; i++) cin >> b[i];
	cin >> q;
	w();
	int s, x, y;
	for (int i = 1; i <= q; i++) {
		cin >> s >> x >> y;
		tot = tot * ksm(((a[s] + b[s]) % mod), mod - 2) % mod * ((x + y) % mod) % mod;
		long long inv = ksm(b[s], mod - 2);
		f[0] = f[0] * inv % mod;
		for (int j = 1; j < c; j++) f[j] = (f[j] - f[j - 1] * a[s] % mod + mod) % mod * inv % mod;
		long long ans = 0;
		for (int j = c - 1; j >= 1; j--) {
			f[j] = (f[j - 1] * x % mod + f[j] * y % mod) % mod;
			ans = (ans + f[j]) % mod;
		}
		f[0] = f[0] * y % mod;
		ans = (ans + f[0]) % mod;
		a[s] = x;
		b[s] = y;
		cout << (tot - ans + mod) % mod << '\n';
	}
	return 0;
}
posted @   Peppa_Even_Pig  阅读(10)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· 使用C#创建一个MCP客户端
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· Windows编程----内核对象竟然如此简单?
点击右上角即可分享
微信分享提示