题目链接: Cyclic Permutations
大致题意:
给定一个n, 你可以任意排列1-n这n个数字, 并按照下述规则以这n个数字建立一张图:
对于每一个下标i, 分别在它的左右找到离他最近的j1和j2, 且要满足a[i] < a[j], 如果能找到则添加i与j之间的无向边, 否则什么也不做.
询问: 有多少种排列能使得图中出现环.
解题思路:
我们可以模拟最简单的情况(n=3), 我们发现只有213和312两种情况.
我们发现如果要成环. 应该至少存在一个三元组a, b, c. 满足a>b && c>b. (对于多元组, 也一定会包含三元组, 所以考虑三元组的情况即可.) 如果我们正向去想, 会发现情况很复杂, 甚至还需要考虑去重. 但是如果我们反向去想, 对于n个数字, 全排列的种类有n!种, 而对于不符合的情况, 我们用n!减去即可得到答案. 而不符合的情况, 则是对于任意一个三元组a, b, c, 都有a<b || c<b. 我们不妨从大到小放置这n个数, 组成不能成环的情况. 假设n已经被放置在某个位置, 则n-1位于其左侧或者右侧均可以, n-2也是位于左右放置都可以, 我们只要保证放置的顺序不改变(大到小), 且每次放置的位置都挨着之前放置的数字, 这样每当我们放置一个数字x, 与他相邻的(比他先放置的)那个数字一定会大于它. 现在我们就得到了不符合条件的数量是2n-1. 因此得到答案: n! - 2n-1.
AC代码:
#include <bits/stdc++.h>
typedef long long ll;
using namespace std;
const int mod = 1E9 + 7;
int main(void)
{
int n; cin >> n;
ll a = 1, b = 1;
for (int i = 1; i < n; ++i) {
a = (a * i) % mod; b = (b * 2) % mod;
}
a = (a * n) % mod;
cout << (a - b + mod) % mod << endl;
return 0;
}
队友强, 夸夸他.