Luogu P11159 【MX-X6-T5】再生 题解
简单数学题。
首先根不同肯定是在诈骗,最长的链的链顶就是树根。然后考虑一条长链内,除了链顶都可以随意排序,对于每条链,答案乘上链中元素数量减一的阶乘。
然后考虑把这些链提取出来,重新拼接成一棵树。注意到如果先拼短链再拼长链,长链会影响到短链,限制较多,而先拼长链再拼短链限制更容易满足,考虑先拼长链。
对于每一条拼过的链,为了满足其长链剖分性质,如果这条链的长度为 ,则长度为 的新拼的链只能拼在较高的 个位置中,否则会破坏长链剖分性质。不难发现对于每一条拼过的链都有这个限制,而我们已经拼上去的链的总长度是已知的,拼过的链的数量也是已知的,所以减去的总量也是已知的,两者做差就是这条链的拼接方案数,乘法原理贡献到答案里即可。
#include <bits/stdc++.h>
using namespace std;
long long n,a[600000],c[600000],s[600000],jc[600000],siz[600000],ans=1,cnt=0;
const long long mod=20051131;
int main()
{
scanf("%lld",&n);
jc[0]=1;
for(int i=1;i<=n;i++)jc[i]=jc[i-1]*i%mod,siz[i]=0;
for(int i=1;i<=n;i++)scanf("%lld",&a[i]),siz[a[i]]++;
for(int i=1;i<=n;i++)
{
if(siz[i]==0)continue;
c[++cnt]=siz[i],ans=ans*jc[siz[i]-1]%mod;
}
sort(c+1,c+cnt+1);
for(int i=cnt;i>=1;i--)s[i]=s[i+1]+c[i];
for(int i=1;i<=cnt-1;i++)ans=ans*(s[i]-(cnt-i+1)*c[i])%mod;
printf("%lld\n",ans);
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探