0%

START200——Permutation Counting (Easy)

思路讲解

题意就是计数问题,求满足i[2,N],  Pi1+Pi≢0(modK)\forall i\in[2,N],\ \ P_{i-1}+P_i\not\equiv0\pmod K 的排列有几个?

首先,看题面,我们发现 i=1TNi2e5∑_{i=1}^{T}N_i≤2e5,因此最终算法是O(nlogn)O(n\log n) 或者 O(n)O(n)

然后我们猛然发现,K=3K=3,确实,我们觉得束手无策是对的,因为如果没有这个条件,是3000+的题目。

那么看着这个数据,我们容易想到dp,dp[i]dp[i] 表示1i1\cdots i 这个排列有可能的总数量(状态定义与答案保持一致)。

但是我们发现这个转移还是比较难的,因为我们用插入一个数字的想法的话,不仅就是说这个原来的合法序列上能够插入,原来的非法序列上也能够插入,变为合法序列,这就导致dp数组存储的信息没有什么意义。

因此,我们还是回到组合数学上,可以令除以3之后余数为0,1,2的分别为r0,r1,r2r_0,r_1,r_2

不难发现,r0r_0r0r_0 不能放在一起,r1r_1r2r_2 也不能放在一起。那么总体结构类似于 r1r0r2r_1|r_0|r_2 或者 r2r0r1r_2|r_0|r_1

不难发现,如果我们直接固定 r0r_0,接着去填充 r1r_1 和 $r_2 $,这相当于解决:

r0+1r_0+1个盒子,其中有r01r_0-1个必须装有球,且一个盒子装的球必须为同一种(一共只有两种),注意,可以理解为球带有编号,且放入盒子的顺序是重要的,盒子也是不同的。

这个问题是比较难解决的,不如我们先确定r1r_1r2r_2,然后填充 r0r_0 这样会简单很多。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
// 我们按照交替进行分类,就是1-0-2-0-1是可以的,1-0-1-0-2,我们按照1-0-2处理。
// 为什么那?说多了都是泪,详细可以看下面的踩坑代码。
FOR(i,2,r0+1){
if(i&1){
for(int j=i/2;j<=i/2+1;++j){
ll other=i-j;
// stars and bars
ll lans=CC(r1-1,j-1)*CC(r2-1,other-1)%mod;
// 多余0的摆放
// 一共有r1+r2+1个位置,有i-1个位置被用掉了,剩余r0-i+1个0
lans*=CC(r1+r2+1-i+1,r0-i+1);lans%=mod;
ans+=lans;
ans%=mod;
}
}else{
for(int j=i/2;j<=i/2;j++){
ll other=i-j;
// stars and bars
ll lans=CC(r1-1,j-1)*CC(r2-1,other-1)%mod;
if(j==i/2) lans*=2;
lans*=CC(r1+r2+1-i+1,r0-i+1);lans%=mod;
ans+=lans;
ans%=mod;
}
}
}

将1-0-1-0-2和1-0-1-0-2视为相同(r1的位置可以重新排列,但这属于重复计数)的缺点。实际上,如果我们在最后乘以P(r1,r1),我们就将r1的块视为相同。当然,r2也是相同的。

AC代码

心路历程(WA,TLE,MLE……)