标签:等于 strong ++ ns2 n+1 计算 解释 长度 lang
我们如果要算一个长度\(2n\)的数列,使它前\(n\)位的和与后\(n\)位的和相等,奇数位与偶数位相等。
选数:
我们先选出\(2\)个长度为\(n/2\)和\((n+1)/2\)的序列编号为\(A\)和\(B\)去填充前\(n\)个数。
然后选出另外\(2\)个序列\(A‘\)和\(B’\)(\(A‘\)和\(A\)长度相等,总和相等,\(B‘\)和\(B\)长度相等,总和相等,也就是说这一共是四个不一定完全相同的序列),去填充后\(n\)个数。
构成:
那么我们可以将最终的长为\(2n\)的序列前\(n\)个数由\(A\)和\(B\)组成,后\(n\)个数用\(A‘\)和\(B’\)组成。这样保证了前后相等(都等于\(A+B\))。
对于奇偶位上的和相等,我们把\(A\)放在最终长为\(2n\)的序列前\(n\)个数中,并充当奇数位,将\(B\)放在前\(n\)个数中并充当偶数位。对于后\(n\)个数颠倒一下,将\(A‘\)充当后\(n\)个数的偶数位,\(B’\)充当奇数位,这样即可保证整个\(2n\)的序列奇偶位上的和相等(都等于\(A+B\))。
方案数:
根据上面的推理,所以我们就要计算的方案数就是在一个\(n\)的序列中选四个长度分别为\(n/2\) 和 \((n+1)/2\) 和 \(n/2\) 和 \((n+1)/2\)的总和相等的序列的方案数。
再总结一下,我们需要控制的是\(A和A‘\)总和相等,长度都是\((n+1)/2\);\(B和B‘\)总和相等,长度都是\(n/2\)。也就是说\(A\)和\(B\)(或者\(A‘和B‘\)或者\(A和B‘\)或者\(A‘和B\))没有必然联系,可以任意组合,但是相同的字母的序列有一定联系。
对于代码:
int lj=(n+1)/2,lo=n/2;
for(int i=0;i<=lj*Max;++i)(ans1+=f[lj][i]*f[lj][i])%=M;//ans1即选出A和A‘的方案数
for(int i=0;i<=lo*Max;++i)(ans2+=f[lo][i]*f[lo][i])%=M;//ans2即选出B和B’的方案数
ans=(ans-(ans1*ans2%M)+M)%M;//ans1*ans2就是说在已经确定的许多A A‘ 和B B‘中,任意两组都可以组合的,ans1*ans2就是A A‘ B B‘所有的方案(也就是算重的)
标签:等于 strong ++ ns2 n+1 计算 解释 长度 lang
原文地址:https://www.cnblogs.com/Lour688/p/13324580.html