题目链接

题解

首先,对于每个\(i\)向\(a[i]\)连边.

这样会连出许多独立的环.

可以证明,交换操作不会跨越环.

每个环内的点到最终状态最少交换步数是 \(环的大小-1\)

那么设\(f[i]\)表示环大小为\(i\)的方案数

\[f[i] = \sum_{x+y=i}f[x] * f[y] * g(x,y) * (^{i-1}_{x-1})
\]

其中

\[g(x,y)=\{^{\frac{x+y}{2}{(x+y为偶数且x=y)}}_{x+y(else)}
\]

打标可以发现\(f[n] = n^{n-2}(n≠1)\)

那么假设有\(k\)个环,第\(i\)个环大小为\(a[i]\)

\[ans = \prod f[a[i]] *T
\]

\(T\)是把\(n-k\)步分进每个环的方案数

\(T=\frac{(n-k)!}{\prod(a[i]-1)!}\)

还有另一种方法算\(T\)(具体看代码)

Code

#include<bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10, Mod = 1e9 + 9;
int fpow(int a, int b) {
if (b <= 0) return 1;
int res = 1;
for (; b; b >>= 1, a = 1ll * a * a % Mod) if (b & 1) res = 1ll * res * a % Mod;
return res;
}
bool vis[N];
int to[N], a[N];
int dfs(int x) {
vis[x] = 1;
if (vis[to[x]]) return 1;
else return 1 + dfs(to[x]);
}
int fac[N], ifac[N];
int C(int n, int m) {
if (n < m) return 0;
return 1ll * fac[n] * ifac[n - m] % Mod * ifac[m] % Mod;
}
void solve() {
int n, ans = 1;
scanf("%d", &n);
for (int i = 1; i <= n; i++) scanf("%d", &to[i]);
memset(vis, 0, sizeof(vis));
int len = 0;
for (int i = 1; i <= n; i++)
if (!vis[i])
a[++len] = dfs(i);
// for (int i = 1; i <= len; i++) ans = 1ll * ans * fpow(a[i], a[i] - 2) % Mod * ifac[a[i] - 1] % Mod;
for (int i = 1, sum = 0; i <= len; sum += a[i++] - 1)
ans = 1ll * ans * fpow(a[i], a[i] - 2) % Mod * C(n - sum - len, a[i] - 1) % Mod;
printf("%d\n", /*1ll * ans * fac[n - len] % Mod*/ans);
return ;
}
int main() {
int T;
scanf("%d", &T);
fac[0] = 1;
for (int i = 1; i <= 100000; i++) fac[i] = 1ll * fac[i - 1] * i % Mod;
ifac[100000] = fpow(fac[100000], Mod - 2);
for (int i = 100000; i >= 1; i--) ifac[i - 1] = 1ll * ifac[i] * i % Mod;
while (T--) solve();
return 0;
}

luoguP4778 Counting swaps的更多相关文章

  1. CH3602 Counting Swaps

    题意 3602 Counting Swaps 0x30「数学知识」例题 背景 https://ipsc.ksp.sk/2016/real/problems/c.html Just like yeste ...

  2. Counting swaps

    Counting swaps 给你一个1-n的排列,问用最少的交换次数使之变为递增排列的方案数\(mod\ 10^9+7\),1 ≤ n ≤ 10^5. 解 显然最少的交换次数不定,还得需要找到最小交 ...

  3. 洛谷P4778 Counting swaps 数论

    正解:数论 解题报告: 传送门! 首先考虑最终的状态是固定的,所以可以知道初始状态的每个数要去哪个地方,就可以考虑给每个数$a$连一条边,指向一个数$b$,表示$a$最后要移至$b$所在的位置 显然每 ...

  4. luogu P4778 Counting swaps

    计数套路题?但是我连套路都不会,,, 拿到这道题我一脸蒙彼,,,感谢@poorpool 大佬的博客的指点 先将第\(i\)位上的数字\(p_i\)向\(i\)连无向边,然后构成了一个有若干环组成的无向 ...

  5. LFYZOJ 104 Counting Swaps

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

  6. lfyzoj104 Counting Swaps

    问题描述 给定你一个 \(1 \sim n\) 的排列 \(\{p_i\}\),可进行若干次操作,每次选择两个整数 \(x,y\),交换 \(p_x,p_y\). 请你告诉穰子,用最少的操作次数将给定 ...

  7. P4778 Counting Swaps 题解

    第一道 A 掉的严格意义上的组合计数题,特来纪念一发. 第一次真正接触到这种类型的题,给人感觉好像思维得很发散才行-- 对于一个排列 \(p_1,p_2,\dots,p_n\),对于每个 \(i\) ...

  8. 0x36 组合计数

    组合计算的性质: C(n,m)= m! / (n!(m-n)!) C(n,m)=C(m-n,m); C(n,m)=C(n,m-1)+C(n-1,m-1); 二项式定理:(a+b)^n=sigema(k ...

  9. 萌新笔记——Cardinality Estimation算法学习(二)(Linear Counting算法、最大似然估计(MLE))

    在上篇,我了解了基数的基本概念,现在进入Linear Counting算法的学习. 理解颇浅,还请大神指点! http://blog.codinglabs.org/articles/algorithm ...

随机推荐

  1. SAS学习笔记19 SAS删除空格函数(left、right、trim、strip、compress、compbl函数)

  2. JS 07 Dom

    DOM(Document Object Model): 结点的概念:整个文档就是由层次不同的多个节点组成,可以说结点代表了全部内容. 结点类型 1.元素结点 2.属性结点 3.文本结点   结点的注意 ...

  3. CentOS7.x使用overlay2文件系统

    当我查看docker详细信息时会看到如下警告: WARNING: devicemapper: usage of loopback devices is strongly discouraged for ...

  4. 部署java应用的几种方式

    J2EE应用 该应用根目录下有好多文件夹和以jsp结尾的文件 部署时,需要在tomcat的conf目录下的server.xml文件中添加上<Context path="/" ...

  5. springboot启动流程(六)ioc容器刷新前prepareContext

    所有文章 https://www.cnblogs.com/lay2017/p/11478237.html prepareContext方法核心逻辑 上一篇文章中,我们通过createApplicati ...

  6. JavaScript知识点:分支结构(if、switch)+算法例题

    if-else分支 1.if条件应该是boolean类型的值或表达式 2.如果条件不是Boolean,会进行自动转换 以下几种情况会默认转换为 false: if(0).if(0.0) if(NaN) ...

  7. MyCAT详解【转】

    原文链接:MyCAT详解 作者:Rangle 一.MyCAT概述MyCAT是一款由阿里Cobar演变而来的用于支持数据库读写分离.分片的分布式中间件.MyCAT可不但支持Oracle.MSSQL.MY ...

  8. ulimit用法

    ulimit -a:显示当前所有的资源限制 -c:core文件大小 -f:设置创建文件的最大值 -n:设置内核可以同时打开的文件描述符的最大值 -p:设置管道缓冲区的最大值 -s:设置堆栈的最大值 - ...

  9. redis修改大key报Argument list too long的解决办法:

    线上一个业务出现异常:redis的一个大大大大大key数据有问题,所以导出修改再导入,但遇到了问题: [root@ ~]# /usr/local/redis/bin/redis-cli -h 127. ...

  10. ASE —— 第二次结对作业

    目录 重现基线模型 基线模型原理 模型的优缺点 模型重现结果 提出改进 改进动机 新模型框架 评价合作伙伴 重现基线模型 基线模型原理 我们选用的的模型为DeepCS,接下来我将解释一下它的原理. 我 ...