luogu P4931 情侣?给我烧了!

|

莫名觉得之前容斥学的是假的,还没有证实。

这题并没有容斥,打上容斥标签是因为我是智障。

传送门

错解:

$f_i$表示至少i组情侣和谐的方案数,其他随便坐,那么:

$f_i=(^n_i)^2\times2^i\times i!\times (2n-2i)!$

表示从n对中选出i对坐在从n排中选出的i排上$((^n_i)^2)$,每一对可以相互交换$(2^i)$,其他随便坐$((2n-2i)!)$。

之后或许可以容斥(由此看出我失败了)。

正解:

加强版一看就是要我们$O(1)$算出一个结果,其实一直都有个想法:

$f_i=(^n_i)^2\times2^i\times i!\times 除了我们选出的情侣其他都分开的方案数$

感觉后面很像错排公式,于是去学习了一下P1595的题解,(抄普及-的题解真好玩),第一篇题解讲的特别好。

那么这个方案数就是$d_{n-i}$($d_i=(i-1)\times(d_{i-1}+d_{i-2})$),不过这似乎不大对,根据你在之前那个题解里看到的推导,是定住第n个箱子,在$[1,n-1]$中选球再讨论,然而我们这个问题男和女都可以做箱子,所以递推式要变成$d_i=2(i-1)\times(d_{i-1}+d_{i-2})$。而且,被钦定分开的$n-i$对情侣还有$2^{n-i}$种坐法。

所以:$f_i=(^n_i)^2\times2^i\times i!\times d_{n-i}\times 2^{n-i}$

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
27
28
29
30
31
#include<cstdio>
#include<iostream>
#define mod 998244353
#define ll long long
using namespace std;
ll jc[5000001],ny[5000001],so[5000001];
ll po[5000001],cp[5000001],f[5000001];
int n,k,t;
inline ll C(int x,int y){
return jc[y]*ny[y-x]%mod*ny[x]%mod;
}
int main(){
scanf("%d",&t);
cp[0]=ny[1]=ny[0]=so[1]=jc[0]=jc[1]=po[0]=1; po[1]=2;
for (int i=2; i<=5000000; i++){
jc[i]=jc[i-1]*i%mod;
so[i]=(mod-mod/i)*so[mod%i]%mod;
ny[i]=ny[i-1]*so[i]%mod;
po[i]=po[i-1]*2%mod;
cp[i]=2*(i-1)*(cp[i-1]+cp[i-2])%mod;
}
while (t--){
scanf("%d%d",&n,&k);
// for (int i=0; i<=n; i++)
// f[i]=C(i,n)*po[n]%mod*jc[i]%mod*C(i,n)%mod*cp[n-i]%mod*jc[n-i]%mod;
// for (int i=0; i<=n; i++) printf("%lld\n",f[i]);
printf("%lld\n",C(k,n)*po[n]%mod*jc[k]%mod*C(k,n)%mod
*cp[n-k]%mod*jc[n-k]%mod);
}
return 0;
}
文章目录
,
载入天数...载入时分秒... 字数统计:75.7k