首页 > 其他分享 >USACO2024JAN 三组连打

USACO2024JAN 三组连打

时间:2024-01-31 14:34:17浏览次数:37  
标签:省流 cnt int tot maxn Delta 三组 USACO2024JAN

假的,只连打了两组。Ag 没时间了。日后再补吧。

无意中存了题面,但代码大部分因为系统还原消失了,只有文字题解,将就着看吧。


Cu - A

省流:任意区间内,若某元素出现个数严格大于区间长度一半,则可将整个区间推平为该值。问最终可以使整个序列被推平为哪些值。

注意到当任意长度 \(\ge 2\) 的区间可以被推平为某种元素时,整个数列都可以被推平为该元素。故目标转化为对于某种元素判定是否存在一个可被其推平的区间。

统计元素个数采用前缀和。令 \(s_i\) 表示 \(h_i\) 在前 \(i\) 项中出现的次数,假设有 \([j,i]\) 满足条件,贪心可知 \(h_i=h_j\)。

那么由定义有 \(i-j+1<2\times (s_i-s_j+1)\)。典中典,直接移项分离变量。则有 \(i-2\times s_i-1<j-2\times s_j\)。令 \(t_p\gets p-2\times s_p\),对于每个 \(h\) 记录 \(t_j\) 最大值查看是否有 \(i,j\) 满足条件即可。

Cu - B

省流:有 \(N\) 个格子,从 \(s\) 格子开始以 \(1\) 为初始能量向右跳,跳一步的距离为能量大小。格子分两种,一种经过加一定能量并反向,另一种若当前能量大于一定值则可永久摧毁,问跳出范围或无限长时间后可摧毁格子个数。

不难发现若忽略增加能量为 \(0\) 的跳板则每经过一个跳板可跳距离增加 \(1\),最多增加到 \(n\),否则会跳出去。

注意到调和级数,故直接模拟跳的过程。唯一导致时间无限的情况是存在相邻的增加能量为 \(0\) 的跳板,但其实它具体是什么并不重要,反正我们跳的次数严格大于调和级数后就可以认为进入死循环,直接结束模拟即可。我这里嫌麻烦直接拿了 \(2\times 10^8\) 作阈值。

Cu - C

省流:定义一次操作为选取一个整数 \(\Delta\le N\),并从 \(N\) 到 \(1\),令 \(a_i\gets a_i+\Delta\) 并令 \(\Delta\) 向 \(0\) 靠近 \(1\),\(\Delta=0\) 时停止。问令所有 \(a_i=0\) 所需最少操作次数。

挺有意思的思维题,首先需要进行一个思维转化。\(\Delta\le N\) 是一个利于解题的限制,这意味着我们想让任何一个 \(a_i\) 改变 \(1\) 而不影响到之前的值,从让 \(a_1\gets 0\) 入手,进行一次操作后每个 \(a_i\) 分到的 \(\Delta\) 应依次加 1 或依次减 1。则差分数组为 \(0\) 后跟着一截 \(1\) 是理想状态。中间每有一项不满足规律都会带来额外的操作次数。

归纳为差分数组的差分数组绝对值之和即为答案。


Ag - A

省流:有若干条限制,每条形如 \(\max\limits_{i=1}^{a_h-1}\{A_i\}=\max\limits_{i=1}^{a_j}\{A_i\}\) 且 \(A_{a_h}>\max\limits_{i=1}^{a_h-1}\{A_i\}\),部分数已知,构造出符合条件且字典序最小的序列。

是本场最难题吧,但也没啥卡的。画个线段图容易发现,若将 \([a,h)\) 视作一条线段,那么除非 \(h\) 相同,否则两条线段不能有交集。不然的话就无解。以及如果存在不满足条件的定值也显然无解。

从前往后看每个 \(h\) 并尝试赋值,对于每个 \(1\sim a\) 记录一个需要满足的最大值数值,按照此数值从后往前填空格。

填完过后扫一遍看看是不是全部合法,可以证明若此时不合法则无解。

Ag - B

省流:一棵树,每个点上有若干个物品,对于每条从根到叶子的简单路径,可以选择路径上的一个物品,每个物品只能被选一次,问最多可选物品数。

如果一个点引导的子树下所有叶子有没有分配到的,就可以把这个点的物品分配给该叶子。

跑一个树形 DP 即可。

namespace XSC062 {
using namespace fastIO;
const int maxn = 1e5 + 5;
int n, x, y;
int cnt[maxn];
std::vector<int> g[maxn];
int a[maxn], f[maxn], p[maxn];
int min(int x, int y) {
	return x < y ? x : y;
}
void DFS(int x, int fa) {
	if ((int)g[x].size() == 1)
		cnt[x] = 1;
	for (auto i : g[x]) {
		if (i == fa) continue;
		DFS(i, x);
		f[x] += f[i];
		cnt[x] += cnt[i];
	}
	if (f[x] < cnt[x])
		f[x] = min(f[x] + a[x], cnt[x]);
	return;
}
void add(int x, int y) {
	g[x].push_back(y);
	return;
}
int main() {
	read(n);
	for (int i = 1; i <= n; ++i) read(p[i]);
	for (int i = 1; i < n; ++i) {
		read(x), read(y);
		add(x, y), add(y, x);
	}
	int tot = 0;
	for (int i = 2; i <= n; ++i)
		tot += ((int)g[i].size() == 1);
	for (int i = 1; i <= tot; ++i) ++a[p[i]];
	DFS(1, -1);
	print(f[1], '\n');
	return 0;
}
} // namespace XSC062

Ag - C

省流:对于给定的序列 \(a\),找出所有满足 \(a_i\bmod L\) 的值的种类最多为 3 的 \(L\)。

也是挺有意思的数学题了。若将 \(a_i\) 按照模 \(L\) 的情况分组,则对于任意一个 \(a_i\),在 \((a_i,a_i+L)\) 中最多包含两个分别来自其余两组的数。

对于去重后 \(n>3\) 的情况,由鸽巢得必定有两个数可分为一组。故我们枚举可能的组间间隔,而可能的 \(L\) 就是这些间隔的因数。

由上面我们推出一个合法组间间隔中最多间隔三个数,我们将所有 \(a_{i+3}-a_i\)、\(a_{i+2}-a_i\) 和 \(a_{i+1}-a_i\) 纳入考虑范围即可。对于所有可能的 \(L\),直接 \(\mathcal O(n)\) 跑一个 check 检查是否合法。

因子个数照理来说是 \(\sqrt{V}\times n\) 级别的,但是实测 \(n\) 最多只有一百多。估计是因为 \(n\) 太大就很难构造出更多的合法解吧。

#define int long long
namespace XSC062 {
using namespace fastIO;
const int maxn = 1e4 + 5;
const int maxm = 3e4 + 5;
std::set<int> u;
int n, res, mn, tot;
int a[maxn], b[maxm];
bool check(int x) {
	int l1 = 0, l2 = 0, l3 = 0;
	for (int i = 1; i <= n; ++i) {
		if (l1 == 0) l1 = a[i];
		else if (x && (a[i] - l1) % x == 0) l1 = a[i];
		else if (l2 == 0) l2 = a[i];
		else if (x && (a[i] - l2) % x == 0) l2 = a[i];
		else if (l3 == 0) l3 = a[i];
		else if (x && (a[i] - l3) % x == 0) l3 = a[i];
		else return 0;
	}
	return 1;
}
int main() {
	read(n);
	for (int i = 1; i <= n; ++i) {
		read(a[i]);
		if (!mn || a[i] / 4 < mn) mn = a[i] / 4;
	}
	std::sort(a + 1, a + n + 1);
	n = std::unique(a + 1, a + n + 1) - a - 1;
	if (check(0)) {
		print(mn * (mn + 1) / 2, '\n');
		return 0;
	}
	for (int i = 2; i <= n; ++i) {
		b[++tot] = a[i] - a[i - 1];
		if (i >= 3) b[++tot] = a[i] - a[i - 2];
		if (i >= 4) b[++tot] = a[i] - a[i - 3];
	}
	std::sort(b + 1, b + tot + 1);
	tot = std::unique(b + 1, b + tot + 1) - b - 1;
	for (int i = 1; i <= tot; ++i) {
		if (check(b[i])) {
			for (int j = 1; j * j <= b[i]; ++j) {
				if (b[i] % j == 0)
					u.insert(j), u.insert(b[i] / j);
			}
		}
	}
	for (auto i : u) {
		if (i > mn) break;
		res += i;
	}
	print(res, '\n');
	return 0;
}
} // namespace XSC062
#undef int

标签:省流,cnt,int,tot,maxn,Delta,三组,USACO2024JAN
From: https://www.cnblogs.com/XSC062/p/17998090

相关文章

  • drf 认证、权限、频率三组件
    一、认证组件判断用户是否登录,数据库是否有值1、需求:通过认证组件去认证,没有认证通过的用户不让登录。认证方式前端发来的token值与数据库进行对比2、modelsfromdjango.dbimportmodelsclassUser(models.Model):username=models.CharField(max_length=32)......
  • 计应211第三组网上鲜花销售系统项目设计
    一:三层架构1.Dao层,数据库访问层,访问数据库,对数据进行增删改查。2.Service层,业务逻辑层,处理事务,收款金额,等。3.Web层,表示层,处理数据,保存数据。二:1.用例图2.活动图3.类图 ......
  • Linux下三组I/O复用函数的比较(select、poll、epoll)
        前面我们讨论了select、poll和epoll三组I/O复用系统调用,这三组系统调用都能同时监听多个文件描述符。它们将等待由timeout参数指定的超时时间,直到一个或多个文件描述符上有事件发生时返回,返回值是就绪的文件描述符的数量。返回0表示没有事件发生。现在我们从事件集、最......
  • Vue2.0 学习 第三组 条件语句
    本笔记主要参考菜鸟教程和官方文档编写。1.v-if在div或者之类的dom中使用v-if可以控制是否插入该dom,控制由v-if的true和false决定。如:<divid="app"><divv-if="test"></div></div><script>newVue({el:"#app",data:{test:true}})</script>2.v-show......
  • 软件工程第三组
    说明图标项目背景经过调研,我们发现,超市、菜场的鱼类种类较为限制,有时新鲜程度也很难保证。用户在选购时,较难选择到各种品质的鱼类,并且对于从未品尝过的鱼类,在烹饪时可......
  • 2022-08-15 第三组 陈迪 学习笔记
    Myspl数据库:数据库:数据库【按照数据结构来组织、存储和管理数据的仓库】。是一个长期储存在计算机内的、有组织的、可共享的、统一管理的大量数据的集合。数据对于......