Luogu4448
什么鬼啊。似乎是个有技巧的容斥。
与 CF840C 是重题。(结果 Devin 还布置过)
注意到这是一个等价关系,直接转化问题,把每个数变成其等价类中钦定的代表元方便分类。
考虑到可以把等价类理解成染色,即序列相邻不能同色,且等价类内部带标号。
然后枚举标号顺序,再对每种颜色上容斥,得到:
\[a!\sum_k(-1)^k\binom{a-1}k{z^{a-k}\over(a-k)!}
\]
理由是互不相邻构成子集反演形式,组合意义讨论捆绑法然后考虑挡板法既得,\(\dfrac{z^{a-k}}{(a-k)!}\) 表示指数生成函数。
然后直接把各种颜色 EGF 组合意义标号积卷起来,把 EGF 系数加一起就是答案。
using namespace BF_POLY;
uint Kind[305],Time[305],tp=0;
modint P[305],Q[305];
int main()
{
AnyMod::ChgMod(1e9+7);
uint n;scanf("%u",&n);
P[0]=1;for(uint i=1;i<=300;i++)P[i]=P[i-1]*i;
Q[300]=P[300].inv();for(uint i=300;i;i--)Q[i-1]=Q[i]*i;
for(uint i=0;i<n;i++)
{
uint v;scanf("%u",&v);
for(uint i=2;i*i<=v;i++)while(v%(i*i)==0)v/=i*i;
for(uint i=0;i<=tp;i++)
{
if(i==tp){
Time[i]=1,Kind[tp++]=v;
break;
}
else if(Kind[i]==v){
Time[i]++;
break;
}
}
}
poly W(modvec{1});
for(uint i=0;i<tp;i++)
{
uint a=Time[i];
poly now(a+1);
for(uint i=0;i<a;i++)
now[a-i]=P[a-1]*Q[i]*Q[a-i-1]*((i&1)?AnyMod::Mod-1:1)*Q[a-i];
W*=now*P[a];
}
modint ans;
for(uint i=0;i<W.size();i++)
ans+=P[i]*W[i];
ans.println();
return 0;
}
本文来自博客园,作者:myee,转载请注明原文链接:https://www.cnblogs.com/myee/p/Luogu-solution-p4448.html