Codeforces Round #663 (Div. 2) (A~C题,C题 Good)
比赛链接:Here
1391A. Suborrays
简单构造题,
把 \(n\) 放最前面,接着补 \(1\) ~ \(n - 1\) 即可
1391B. Fix You
\((1,1)\) -> \((n,m)\) 统计相应个数的 R
和 D
即可
char a[110][110];
int main() {
cin.tie(nullptr)->sync_with_stdio(false);
int _; for (cin >> _; _--;) {
int n, m;
cin >> n >> m;
for (int i = 1; i <= n; ++i)
for (int j = 1 ; j <= m; ++j) cin >> a[i][j];
int sum = 0;
for (int i = 1; i < m; ++i) if (a[n][i] != 'R')sum += 1;
for (int i = 1; i < n; ++i) if (a[i][m] != 'D')sum += 1;
cout << sum << "\n";
}
}
1391C. Cyclic Permutations (Good)
先说结论:\(n! - 2^{n - 1}\)
对于任意的循环排列,例如 [4, 2,3,1,5,6]
它包含许多长度为3的循环: [1,2,3],[1,3,5],[3,4,5]
。请注意,所有列出的循环都包含仅从一个i选项中获得的节点。我们可以将其概括为以下几点。如果对于任何一个i,我们在它的两边做边,这将创建一个长度为3的简单循环。证明很简单。
因此,最多只能有一个峰值,即元素 \(n\) ~ 所有非循环排列都会增加,然后达到 \(n\) ,最后减少。这些形式上称为单峰置换,很容易看出,任何单峰置换都形成一棵树,因此不包含简单的循环-除了n之外,每个元素都有一个唯一定义的父元素。
我们可以通过将数字n,n相加来构造任何单峰排列−1,…,1按相同顺序排列成一个三角形。例如,[2,3,4,1]可以通过先将4,3,2推到前面,最后将1推到后面来构造。因此,对于除n之外的每个元素,我们可以选择将其推到前面或后面,使路径总数等于 \(2^{n - 1}\) .
const int mod = 1e9 + 7;
int main() {
cin.tie(nullptr)->sync_with_stdio(false);
int n;
cin >> n;
ll a = 1, b = 1;
for (int i = 1; i <= n; ++i) a = a * i % mod;
for (int i = 1; i < n; ++i) b = b * 2 % mod;
cout << (a + mod - b) % mod;
}