https://www.luogu.org/problemnew/solution/P4778

非常好的题目,囊括了乘法加法原理和多重集合排列,虽然最后使用一个结论解出来的。。

给定一个n的排列,用最少的次数将排列变成单调递增
请问这样的操作有多少种

套路:位置i向位置p[i]连单向边,最后会形成l个环
先来考虑单个环:
引理:将长度为len的环拆成len个自环至少操作len-1次

套路:

一个数对应有且仅有一个位置,且一个位置有且仅有一个数

这就意味着整个图上每个点入度出度都为1

也就意味着图上的环都是简单环

于是DFS找环并统计长度可以用很简单的代码实现

每次交换操作实际上是交换边,在单向边组成的环中交换任意两条边后必定形成两个独立的环

即每次交换操作会将len的环拆成长度为x,y的两环

那么考虑有多少种拆法T(x,y)=(x==y?x:x+y)种拆分方式

设F[len]为将长度len的环拆成len个自环的操作方法数

显然有F[len]=sum{先拆成(i,len-i)的方法数}

那么先拆成(i,len-i)的方法数=T(i,len-i)*F[i]*F[len-i]*step(i,len-i)

由于把长为i的环拆成自环要i-1步,长len-i的环拆成自环要len-i-1步,这些步数可以先后穿插,但是一个环集合内自己的步数本可以打乱,所以等价于可重集合的排列数

由多重集的排列数,总共有step(i,len-i)=(len-2)!/(i-1)!*(len-i-1)! 种步数

所以最后一个长为len的环的公式是

F[len]=sum:T(i,len-i)*F[i]*F[len-i]*(len-2)!/(i-1)!*(len-i-1)!

所以最终答案是所有环相乘 ,再乘可重集合的排列数,即环于环相乘时步数也是可以先后穿插的!

事实上,有F[len]=len^(len-2)的结论

最新文章

  1. linux常用命名复习
  2. 开启ACM的征途
  3. twisted 安装时,安装顺序为 zope.interface ->twisted
  4. UVa 10256 凸包简单应用
  5. Java调度框架Quartz简单示例
  6. JAVA经典算法40题
  7. VMware虚拟机安装教程
  8. 设计模式之迭代器模式——Java语言描述
  9. week7 ls
  10. [转]Oracle left join \ right join
  11. Oracle字符串函数
  12. Gold Rush(hnu13249)
  13. MySQL更改了my.ini的#Path to the database root后,数据还写到原来的文件夹
  14. Qt通过ODBC来操作Excel
  15. appium安装与部署
  16. Use a TL431 shunt regulator to limit high ac input voltage
  17. 浅谈https\ssl\数字证书
  18. nyoj 456——邮票分你一半——————【背包思想搜索】
  19. BZOJ2877 [Noi2012]魔幻棋盘
  20. iOS编程规范(整理)

热门文章

  1. (6)Java数据结构-- 转:JAVA常用数据结构及原理分析
  2. Centos7配置静态IP后无法ping通外部网络的问题(无法上网)
  3. protobuf 安装与卸载
  4. 论文笔记:Joint Embeddings of Shapes and Images via CNN Image Purification
  5. python3之模块SMTP协议客户端与email邮件MIME对象
  6. VS2013中如何解决error C4996: 'fopen'问题
  7. 设置Vmware中Kali_linux 共享文件夹
  8. MVC之基架
  9. java泛型类型变量能调用的方法
  10. Ex4_21 最短路径算法可以应用于货币交易领域..._第十二次作业