Counting swaps

给你一个1~n的排列,问用最少的交换次数使之变为递增排列的方案数\(mod\ 10^9+7\),1 ≤ n ≤ 10^5。

显然最少的交换次数不定,还得需要找到最小交换次数,而考虑到交换为复杂的过程,考虑状态的性质,所以不难想到画出,+为箭头指向方向

 _   _
| + | +
2 1 4 3
+ | + |
|_| |_|

于是你会发现实际上我们的变换为递增序列,即把所有的环都变成自环,而交换两个数字即拆环,所以不难知道,一个环拆掉的最少的次数为环的大小-1(因为你对一个环进行一次交换操作,就变成了两个环,以此类推,拆成n个环,要操作n-1次)。

有了这样一个想法,于是考虑环的组合计数问题的方法,可以以拆环为状态划分来设递推方程,于是设\(f[i]\)表示长度为i的环的变成全部是自环的最少操作次数的方案数,拆成两个环又有不同的拆分方式,于是设\(T[i][j]\)表示拆成两个长i,j的环的方案数,于是我们有

\[T[i][j]=i==j?i+j>>1:i+j\]

\[f[i]=\sum_{j=1}^{[i/2]}f[j]\times f[i-j]\times T[j][i-j]\times\frac{(i-1)!}{(j-1)!(i-j)!}\]

于是,设初始序列为长\(l_1,l_2...,l_m\)的环构成的,易知

\[ans=(n-m)!\prod_{i=1}^mf[l_i]\frac{1}{(l_i-1)!}\]

但是对于f找规律,我们发现\(f[i]=i^{i-2}\),于是我们可以利用矩阵快速幂,时间复杂度应为\(O(nlog(n))\)。

参考代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#define il inline
#define ri register
#define ll long long
#define yyb 1000000009
#define lsy 1000000007
#define _ putchar('\n')
using namespace std;
int num[100001];
bool check[100001];
ll dp[100001],jc[100001],jv[100001];
il ll pow(ll,ll);
il void prepare();
template<class free>void pen(free);
template<class free>il void read(free&);
int main(){int cjx,i,j,n,len,tot;ll ans;prepare(),read(cjx);while(cjx--){read(n),memset(check,0,sizeof(check));for(i=1;i<=n;++i)read(num[i]);tot&=0,ans=1;for(i=1;i<=n;++i)if(!check[i]){j=i,++tot,len&=0;do j=num[j],++len,check[j]|=true;while(i!=j);ans=ans*dp[len]%yyb*jv[len-1]%yyb;}ans=ans*jc[n-tot]%yyb,pen(ans),_;}return 0;
}
template<class free>
void pen(free x){if(x>9)pen(x/10);putchar(x%10+48);
}
il ll pow(ll x,ll y){ll ans(1);while(y){if(y&1)ans=ans*x%yyb;x=x*x%yyb,y>>=1;}return ans;
}
void prepare(){ri int i,j;jc[1]=jc[0]=jv[1]=jv[0]=dp[1]=1;for(i=2;i<=100000;++i)jc[i]=jc[i-1]*i%yyb,jv[i]=pow(jc[i],lsy),dp[i]=pow(i,i-2);
}
template<class free>
il void read(free& x){x&=0;ri char c;while(c=getchar(),c<'0'||c>'9');while(c>='0'&&c<='9')x=(x<<1)+(x<<3)+(c^48),c=getchar();
}

转载于:https://www.cnblogs.com/a1b3c7d9/p/10796857.html

Counting swaps相关推荐

  1. LFYZOJ 104 Counting Swaps

    题解 #include <iostream> #include <cstdio> #include <algorithm> #include <cmath&g ...

  2. 数数题(计数类 DP)做题记录

    数数题(计数类 DP)做题记录 CF1657E Star MST 我们称张无向完全图是美丽的当且仅当:所有和 \(1\) 相连的边的边权之和等于这张完全图的最小生成树的边权之和. 完全图点数为 \(n ...

  3. 《算法竞赛进阶指南》数论篇(3)-组合计数,Lucas定理,Catalan数列,容斥原理,莫比乌斯反演,概率与数学期望,博弈论之SG函数

    文章目录 组合计数 例题:Counting swaps Lucas定理 Cnm≡Cnmodpmmodp∗Cn/pm/p(modp)C_n^m\equiv C_{n\ mod\ p}^{m\ mod\ ...

  4. DFS:深入优先搜索 POJ-2386 Lake Counting

    深度优先搜索是从最开始的状态出发,遍历所有可以到达的状态. 因此可以对所有的状态进行操作,或列举出所有的状态. Lake Counting POJ - 2386 Due to recent rains ...

  5. Boring counting HDU - 3518 (后缀数组)

    Boring counting \[ Time Limit: 1000 ms \quad Memory Limit: 32768 kB \] 题意 给出一个字符串,求出其中出现两次及以上的子串个数,要 ...

  6. pat1004. Counting Leaves (30)

    1004. Counting Leaves (30) 时间限制 400 ms 内存限制 65536 kB 代码长度限制 16000 B 判题程序 Standard 作者 CHEN, Yue A fam ...

  7. CF990G GCD Counting(树上莫比乌斯反演,分层图,并查集)

    整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 Problem 给定一棵点带权无根树,对于每个 k∈[1,2×105]k\in[1,2\times10 ...

  8. 2019 ACM - ICPC 上海网络赛 E. Counting Sequences II (指数型生成函数)

    繁凡出品的全新系列:解题报告系列 -- 超高质量算法题单,配套我写的超高质量题解和代码,题目难度不一定按照题号排序,我会在每道题后面加上题目难度指数(1∼51 \sim 51∼5),以模板题难度 11 ...

  9. 人群密度估计--Structured Inhomogeneous Density Map Learning for Crowd Counting

    Structured Inhomogeneous Density Map Learning for Crowd Counting https://arxiv.org/abs/1801.06642 针对 ...

最新文章

  1. python程序控制电脑开机_Python3.4实现远程控制电脑开关机
  2. 【Linux学习九】负载均衡
  3. 我为什么不用do{}while()
  4. 跟我学大数据分析:多维度数据分析报告
  5. android网络通信之SOAP教程实例汇总
  6. Python: 反方向迭代一个序列
  7. 联想(Lenovo)小新310经典版进bios方法
  8. 爱情三十一课,先信自己
  9. list按照某个字段排序_恕我直言你可能真的不会java第7篇:像使用SQL一样排序集合
  10. CodeForces 1065E. Side Transmutations 计数
  11. 大整数加法(信息学奥赛一本通-T1168)
  12. “鬼才”论文致谢刷屏!感谢我导“似导非导”的指导……
  13. 隧道工程偷工减料大揭秘一
  14. 毕业2年鏖战美团、京东、阿里3个大厂,成功拿到2个offer,我的社招Java岗面试经历分享
  15. tago fences v2.5
  16. [c++] 使用 raylib + ODE(open dynamics engine) 制作一个简易牛顿摆
  17. 我的世界光影mod怎么用_国际版minecraft mod和光影教程
  18. 5g消息服务器,5G消息开启信息服务新篇章
  19. 关于log4j的参数含义
  20. 电脑打字不显示候选框问题

热门文章

  1. 删除文件夹时,显示“错误0x80070091 文件夹不是空的”
  2. 福清龙华职业中专计算机应用学校什么,福建省福清龙华职业中专学校招生专业|福建省福清龙华职业中专学校有哪些专业...
  3. 用python画画简单代码_Python3使用PyQt5制作简单的画板/手写板实例
  4. 如何给产品引流?一个产品如何做引流?
  5. html页面中艺术字,html 生成艺术字
  6. 清华胡宇迪教授谈关于爱情、关于伴侣、关于承诺、关于人生、关于友情、关于微笑、关于生活、关于幸福
  7. sdut-3386 小雷的冰茶几
  8. Suse linux 关闭防火墙命令,suse防火墙关闭
  9. ubuntu防火墙关闭了为什么扫描端口还是过滤状态
  10. 牛顿?不不不,是牛逼顿