2025.03.08 CW 模拟赛 A. 114514

题面 & 题解

A. 114514

为什么会写挂呢?

题意

对于一个正整数序列 \( b \),定义函数 \( \text{trans}(b) \) 为一个满足以下要求的正整数序列 \( b' \):

  • \( |b| = |b'| \),且 \( b' \) 内的数互不相同。
  • 对于所有满足 \( 1 \leq i \leq |b| \) 的整数 \( i \),有 \( b_i \leq b_i' \)。
  • \( b' \) 是满足以上两个要求的序列中,字典序最小的。

可以证明 \( \text{trans}(b) \) 唯一。例如,\( \text{trans}([1, 1, 4, 5, 1, 4]) = [1, 2, 4, 5, 3, 6] \)。

现在给你一个长度为 \( n \) 的序列 \( a \),满足 \( a \) 中的数互不相同。请你求出满足 \( \text{trans}(b) = a \) 的正整数序列 \( b \) 的个数对 \( 10^9 + 7 \) 取模的值。

可以证明只有有限多个满足要求的序列 \( b \)。

思路

注意到给定的 \(a\) 数组里的数互不相同.

从样例入手, 考虑序列 1 2 4 5 3 6. 显然, 我们序列 \(b\) 的第一个数只能填入 \(a_1\). 对于第二个数 \(a_2 = 2\), 可以发现填入 1 或者 2 都可以满足条件. 但是对于第三个数, 我们只能填 4. \((\)因为如果填入比 4 更小的数我们这一位上就可以取 3 了\()\)

继续模拟一下不难发现, 我们在第 \(i\) 位上可以填入的数字和以 \(a_i\) 为结尾的在 \(1 \sim i - 1\) 前已经使用过数的极长连续段的长度有关.

由于 \(a_i \le 4 \times 10^6\), 这个东西不难用并查集维护, 每次使用了一个数过后将 \(a_i + 1\) 的父亲设为 \(a_i\) 的父亲即可.

int find(int x) { return fa[x] == x ? x : fa[x] = find(fa[x]); }

void calculate() {
	int ans = 1;
	for (int i = 1; i <= n; ++i) {
		fa[a[i] + 1] = fa[a[i]];
		ans = 1ll * ans * (a[i] - find(a[i]) + 1) % mod;
	}
	printf("%d", ans);
}
posted @ 2025-03-09 14:13  Steven1013  阅读(32)  评论(0)    收藏  举报