[cf 1091D]D. New Year and the Permutation Concatenation

再次看了下两年前的题解,觉得还蛮有意思的hhh。不过在一些部分可能表述没那么好。写一份修正版的。
(ps:难顶。修改不可导入外部md,导入就新创建,搞不定了)

题意:给定 n ! n! n! n n n的排列,按字典序从小到大连成一个序列,例如3的情况为:[1,2,3, 1,3,2, 2,1,3 ,2,3,1 ,3,1,2 ,3,2,1]。问其中子段长度为n,且和 s u m = n × ( n − 1 ) ÷ 2 sum=n\times(n-1)\div2 sum=n×(n1)÷2的序列有多少?

(题意来自于:https://www.cnblogs.com/pkgunboat/archive/2018/12/31/10201676.html @维和战艇机,感谢你这么好的总结方式,借用一下希望不要介意)

思路(非官方题解):官方题解下面有种方法是:There is also a simple recurrence counting the same answer, found by arsijo:d(n)=(d(n−1)+(n−1)!−1)⋅n,我比赛时是用这个方法。

现在讨论可能计入答案的情况,分为以下两种情况。

  1. n ! n! n!个组成序列的排列。以3为例,[{1,2,3}, {1,3,2}, {2,1,3} ,{2,3,1} ,{3,1,2} ,{3,2,1}],所有大括号内的都计入答案。
  2. 两个相邻排列组成的答案。也就是一部分在一个排列中,另一部分在下一个排列中的情况,比如[1,{2,3,1},3,2,…],{2,3}属于前一部分,{1}属于后一部分。

显而易见,第一种有 n ! n! n!种情况,接下来推第二种:

首先需要证明,这种情况下的子串,一定都是由n个不同数字组成的情况。有兴趣的同学可以看下,没兴趣的可以跳过证明部分。

设符合的情况所处子段为 p 1 , p 2 p1,p2 p1,p2,其中,在 p 1 p1 p1中长度为 k k k,那么在 p 2 p2 p2中,长度为 n − k n-k nk,以及剩余长度为 k k k。如图所示。

没有描述

此处用反证法来证明,假设存在一个上述情况,符合和为 n × ( n − 1 ) ÷ 2 n\times(n-1)\div2 n×(n1)÷2,且不为n个不同数字组成的情况。

假设上图中,从左往右分别是四块区域,编号为①、②、③、④。其中,①+②= p 1 p1 p1,③+④= p 2 p2 p2

证明1 ∑ ① + ∑ ③ = n × ( n − 1 ) ÷ 2 \sum①+\sum③=n\times(n-1)\div2 +=n×(n1)÷2 ∑ ② + ∑ ④ = n × ( n − 1 ) ÷ 2 \sum②+\sum④=n\times(n-1)\div2 +=n×(n1)÷2

此时,通过定理1,可以推出结论1。

结论1:③区域字典序等于①时,也就是③=①,此时②+③=②+①,可计入答案。

由③区域字典序一定大于等于①,我们接下来讨论③字典序大于①的情况。

证明2:如果③字典序大于①,②部分一定是字典序降序。

推导:反证法。如果②部分不是字典序降序,由于题意 p 2 p2 p2 p 1 p1 p1的next permutation,此时④会是②的next permutation,③部分不会改变,③字典序等于①,与题意不符。

此处需要科普下next permutation的排列变动情况。

定理1:对于 x x x p k p m p m − 1 . . p 1 xxxp_kp_mp_{m-1}..p_1 xxxpkpmpm1..p1,其中 p m > p m − 1 > . . . > p k > . . . > p 1 p_m>p_{m-1}>...>p_k>...>p_1 pm>pm1>...>pk>...>p1 x x x xxx xxx表示任意数。该部分的next permutation为 x x x p k + 1 p 1 . . . p k p k + 2 . . . p m xxxp_{k+1}p_1...p_kp_{k+2}...p_m xxxpk+1p1...pkpk+2...pm

不想证明。

此处添加定义1 p k p_k pk为第一个导致字典序不降序的数字。

证明3:对于定理1中的 p k p m p m − 1 . . p 1 p_kp_mp_{m-1}..p_1 pkpmpm1..p1 p k + 1 p 1 . . . p k p k + 2 . . . p m p_{k+1}p_1...p_kp_{k+2}...p_m pk+1p1...pkpk+2...pm,从左往右取相同的长度 l e n ( 1 < l e n < m + 1 ) len(1<len<m+1) len(1<len<m+1)下,前者大于后者。

证明:当 l e n = 2 len=2 len=2时, p m − p 1 > p k + 1 − p k ⇒ p m + p k > p k + 1 + p 1 p_m-p_1>p_{k+1}-p_k\Rightarrow p_m+p_k>p_{k+1}+p_1 pmp1>pk+1pkpm+pk>pk+1+p1

后续证明写起来有点麻烦。不想写,鸽了。

在两者序号没相交时,由于前者每个添加的数字都大于后者 ,以及差距一定是大于 l e n = 2 len=2 len=2情况;

两者序号相交时,把中间相交部分抵消掉,剩下的跟上面情况差不多。证明3证毕。

利用以上证明定理定义,来证明结论2。

结论2:③区域字典序大于①时,不存在②+③可计入答案的情况。

设③的从左往右第m位的数字是 a m a_m am

由证明2,对 p 1 p_1 p1而言,从右往左可以作为第一个导致字典序不降序的数字是 a n − k a_{n-k} ank。以下对第一个导致字典序不降序的数字进行讨论。

假设1:作为第一个导致字典序不降序的数字是 a n − k a_{n-k} ank

此时next permutation后,由定理1,变为 a n − k ′ a_{n-k}^{'} ank。且 a n − k ′ > a n − k a_{n-k}^{'}>a_{n-k} ank>ank

此时 ③ = ∑ i = 1 n − k − 1 a i + a n − k ′ > ∑ i = 1 n − k a i = ① ③=\sum_{i=1}^{n-k-1}a_i+a_{n-k}^{'}>\sum_{i=1}^{n-k}a_i=① =i=1nk1ai+ank>i=1nkai=。又 ① + ② = n × ( n − 1 ) ÷ 2 ①+②=n\times(n-1)\div2 +=n×(n1)÷2,则 ③ + ② > n × ( n − 1 ) ÷ 2 ③+②>n\times(n-1)\div2 +>n×(n1)÷2,不计入答案。

假设2:作为第一个导致字典序不降序的数字是 a 1 a_1 a1

此时没有next permutation,没有 p 2 p_2 p2,不计入答案。

假设3:作为第一个导致字典序不降序的数字是 a j ( 1 < j < n − k ) a_{j}(1<j<n-k) aj(1<j<nk)

由证明③, ③ < ① ③<① <,不计入答案。

至此,结论2证毕。

由结论1和结论2,这种情况下的子串,一定都是由n个不同数字组成的情况证毕。证明部分完结。

答案统计部分开始。

首先固定③部分长度为k,由排列组合,易得②部分组合种数 A n k A_n^k Ank种。

此时对于②部分长度为n-k,为n个数字删去②中k个数字后剩下的数字组合。排列组合共有 ( n − k ) ! (n-k)! (nk)!种。但由于对于②中字典序最大的,此时的next permutation的前部分已经不会③了,无法计入答案。因此计入答案只有 ( n − k ) ! − 1 (n-k)!-1 (nk)!1种。

总结,对于2的情况,计入答案的情况为 A n k × [ ( n − k ) ! − 1 ] A_n^k\times[(n-k)!-1] Ank×[(nk)!1]种。

综上所述,答案是 n ! + A n k × [ ( n − k ) ! − 1 ] n!+A_n^k\times[(n-k)!-1] n!+Ank×[(nk)!1]

代码就不再打一遍了。hh

#include<stdio.h>
typedef long long ll;
const int maxn = 1e6 + 5;
const ll Mod = 998244353;
	ll a,jie[maxn],djie[maxn],n,res; //jie,djie分别是阶乘和A(n,n-k),res是结果
	
int main()
{
	scanf("%I64d",&n);
	jie[0] = 1; djie[0] = 1;
	for(a = 1;a <= n;a ++)
	{
		jie[a] = jie[a-1] * a % Mod;
		djie[a] = djie[a-1] * (n+1-a) % Mod;		
	}
	res = jie[n];
	for(a = 2;a <= n-1;a ++)
		res = (res + (jie[a] - 1) * djie[n-a] % Mod) % Mod;
	printf("%I64d\n",res);
	return 0;
}

以下是二年前版本


题意:给n!个n的排列,按字典序从小到大连成一条序列,例如3的情况为:[1,2,3, 1,3,2, 2,1,3 ,2,3,1 ,3,1,2 ,3,2,1],问其中长度为n,且和为sum=n*(n+1)/2的序列有多少个?
(题意来自于:https://www.cnblogs.com/pkgunboat/archive/2018/12/31/10201676.html @维和战艇机,感谢你这么好的总结方式,借用一下希望不要介意)

思路(非官方题解):官方题解下面有种方法是:There is also a simple recurrence counting the same answer, found by arsijo:d(n)=(d(n−1)+(n−1)!−1)⋅n,我比赛时是用这个方法。

如官方题解思路,有两种n长度的子序列符合【和为n*(n-1)/2】:
第一种为n!个组成序列的排列;
第二种为一部分在一个排列中,另一部分在下一个排列中的排列。
显而易见,第一种有n!种情况,那下面来推第二种:

对于一个n长度的排列,假设我们先固定前k个元素,那么对于包含这些前k个元素固定的片段,是一系列①前k个元素固定;②后n-k个元素按照字典序从小到大的排列连接而成的,假设这一系列排列的数量为m。

发现这个有什么用呢?现在取出上面那段片段,我们来寻找里面排列为③使用一个排列后n-k个元素④使用下一个排列前k个元素的排列的数量,在上面片段中,能找到的排列都满足,而又由于这些排列夹在上面排列两两之间,可得数量为m-1。(就像对于一个队伍的小朋友,假设两两之间插入一个小朋友,那么插入小朋友的数量为原队伍小朋友的数量-1)。
那么有没有漏网之鱼呢?答案是没有。这个草稿纸上画下,你就明白了。m中满足条件的有m-1种,说明只有一种是不满足的。对于假设考虑只满足③的,那么片段的第一个排列是不满足的,考虑只满足④的话,片段的最后一个排列是不满足的。就不展开了。(不会暴露楼主不想打,,,咔咔)
emm以防卡在奇怪的地方,给上面解释一个应该不会有用的提示吧
现在还有一个问题,就是m未知,现在来求m:
由①,则有A(n,n-k)种;
而对于①的每种情况
由②,有k!种,又由解释需要-1,则有(k!-1)种情况。
至此可以得到一个重要的信息,列为③使用一个排列后n-k个元素④使用下一个排列前k个元素的排列的数量 = A(n,n-k)*(k!-1)。

知道上述公式后,来求答案:
k∈[1,n];
当k=n时,其实就是组成序列的排列,所以用组成序列排列的公式:n!;
当k!=n时,用上面得出的公式A(n,n-k)*(k!-1);
因此答案是n!+∑(k from 1 to n-1) [A(n,n-k)×(k!-1)]。

k)*(k!-1)。

知道上述公式后,来求答案:
k∈[1,n];
当k=n时,其实就是组成序列的排列,所以用组成序列排列的公式:n!;
当k!=n时,用上面得出的公式A(n,n-k)*(k!-1);
因此答案是n!+∑(k from 1 to n-1) [A(n,n-k)×(k!-1)]。

代码我就不再贴一遍了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值