正解:数论

解题报告:

传送门!

首先考虑最终的状态是固定的,所以可以知道初始状态的每个数要去哪个地方,就可以考虑给每个数$a$连一条边,指向一个数$b$,表示$a$最后要移至$b$所在的位置

显然每个数只会有一条出边,也只会有一条入边,所以会构成若干条环然后现在的目标就相当于是要通过最少的次数使所有边都变成自环

然后考虑这个交换操作,就相当于是交换两条边的终点

欧克把题目转化完了下面考虑解题

先证明这样一个结论:一个长度为$n$的环要变成$n$个自环至少需要$n-1$步

证明如下:

考虑用数学归纳法

首先长度为2的环要变成2个自环显然是1步

现在考虑若已证明对长度$<k$的环都成立

则对于长度为k的环,显然随意交换两条边的终点后就变成了一个长度为$x$的环和一个长度为$y$的环,且$x+y=k$

那么分别对这两个环都有最少步骤为$(x-1)+(y-1)=k-2$

再加上第一步交换两条边的终点的操作,总的步骤就要$k-2+1=k-1$步

得证(,,,这个证明挺弱智的我$jio$得

接着考虑设$f[x]:$拆长度为$x$的环为$x$个自环的方案数

为了表达方便再设个$g[x][y]$表示长度为$x+y$的环拆成长为$x$的环和长为$y$的环的方案数

首先显然有$g[x][y]=\left\{\begin{matrix}\frac{n}{2}(x=y)\\n(x\neq y)\end{matrix}\right.$

瞎证明下趴,下面为了表达方便提前解释下,交换点对的意思就是交换终点为这两个点的边的终点(,,,有点绕,怪我语文太差$TT$

显然当$x\neq y$的时候

对任意一个点$x$,会有两个点$y_{1}$,$y_{2}$满足交换$\left ( x,y \right )$之后能拆成一个大小为x的环和一个大小为y的环

然后再考虑重复,就每条边会被枚举两次(显然?就两个断点分别作为起点枚举一次嘛$QwQ$,所以就有$g[x][y]=\frac{n\cdot 2}{2}=n$

然后当$x=y$的时候,就显然只有一个点$y$了,所以就是$g[x][y]=\frac{n}{2}$

证毕

然后考虑$f[x]$的递推式?

不难想到$f[x]=\sum_{i=1}^{\frac{x}{2}}g[i][x-i]\cdot f[i]\cdot f[x-i]\cdot \frac{(x-2)!}{(i-1)!\cdot (x-i-1)!}$

再瞎证下$QAQ$

其实前面都不太难get,就枚举拆成的环有多大,然后拆成大小为$i,x-i$的方案数是$g[i][x-i]$,然后内部拆的方案是$f[i]\cdot f[x-i]$

主要大概是要解释下后面这个 $ \frac{(n-2)!}{ (i-1)! \cdot (n-i-1)!} $

就因为两个环是互相独立互不影响的,所以显然可以先做一步第一个环的,再做一步第二个环的,这样子,所以总共有$(n-2)$步就有$(n-2)!$条方案

但考虑到事实上在分别做两个小环的时候就已经考虑到这个问题已经乘过了,所以就再除以一个$(i-1)!\cdot (n-i-1)!$

(一个$upd:$过了一段时间之后重新来看这题发现我是呆呆,,,?这不就是组合数嘛我在想啥???????$/dk/dk/dk$

但是实际上这儿有个优化,,,因为这个复杂度实际上是过不去的,复杂度$O(n^{2})$的,但是可以打表找规律得$f[i]=i^{i-2}$

不会证啊$QAQ$那就不证了趴$QAQ$

最后考虑因为是有若干个环,同样是因为环之间互不影响可以先做一步这个环的再做一步那个环的这样子,所以最后的$ans$就是 $ (\prod_{i=1}^{k} f_{l_i}) \cdot \dfrac{(n-k)!}{\prod_{i=1}^k(l_i-1)!} $

$aya$好像忘记说$l_i$辣,,,,就是说每个环的大小辣

那就做完辣?等下放代码吼$QwQ!$

#include<bits/stdc++.h>
using namespace std;
#define il inline
#define gc getchar()
#define t(i) edge[i].to
#define int long long
#define ri register int
#define rb register bool
#define rc register char
#define rp(i,x,y) for(ri i=x;i<=y;++i)
#define my(i,x,y) for(ri i=x;i>=y;--i)
#define e(i,x) for(ri i=head[x];i;i=edge[i].nxt) const int N=1e5+,mod=1e9+;
int head[N],ed_cnt,ln[N],ln_cnt,as,n,jc[N],inv[N];
bool vis[N];
struct ed{int to,nxt;}edge[N<<]; il int read()
{
rc ch=gc;ri x=;rb y=;
while(ch!='-' && (ch>'' || ch<''))ch=gc;
if(ch=='-')ch=gc,y=;
while(ch>='' && ch<='')x=(x<<)+(x<<)+(ch^''),ch=gc;
return y?x:-x;
}
il int power(ri x,ri y){if(y<)return ;ri ret=;while(y){if(y&)ret=1ll*ret*x%mod;x=1ll*x*x%mod;y>>=;}return ret;}
il void pre()
{
jc[]=;rp(i,,N-)jc[i]=1ll*jc[i-]*i%mod;
inv[N-]=power(jc[N-],mod-);my(i,N-,)inv[i]=1ll*inv[i+]*(i+)%mod;
}
il void ad(ri x,ri y){edge[++ed_cnt]=(ed){x,head[y]};head[y]=ed_cnt;}
int dfs(ri x,ri fa){if(vis[x])return ;vis[x]=;e(i,x)return dfs(t(i),x)+;} signed main()
{
// freopen("4778.in","r",stdin);freopen("4778.out","w",stdout);
int T=read();pre();
while(T--)
{
memset(vis,,sizeof(vis));memset(head,,sizeof(head));ed_cnt=;ln_cnt=;
n=read();rp(i,,n)ad(i,read());rp(i,,n)if(!vis[i])ln[++ln_cnt]=dfs(i,);
as=jc[n-ln_cnt];rp(i,,ln_cnt)as=1ll*as*power(ln[i],ln[i]-)%mod*inv[ln[i]-]%mod;
printf("%lld\n",as);
}
return ;
}

这儿是代码,,,

洛谷P4778 Counting swaps 数论的更多相关文章

  1. 乘法原理,加法原理,多重集的排列数(多个系列操作穿插的排列数) 进阶指南 洛谷p4778

    https://www.luogu.org/problemnew/solution/P4778 非常好的题目,囊括了乘法加法原理和多重集合排列,虽然最后使用一个结论解出来的.. 给定一个n的排列,用最 ...

  2. 洛谷P4562 [JXOI2018]游戏 数论

    正解:数论 解题报告: 传送门! 首先考虑怎么样的数可能出现在t(i)那个位置上?显然是[l,r]中所有无法被表示出来的数(就约数不在[l,r]内的数嘛QwQ 所以可以先把这些数筛出来 具体怎么筛的话 ...

  3. 洛谷P3104 Counting Friends G 题解

    题目 [USACO14MAR]Counting Friends G 题解 这道题我们可以将 \((n+1)\) 个边依次去掉,然后分别判断去掉后是否能满足.注意到一点, \(n\) 个奶牛的朋友之和必 ...

  4. 洛谷P1134 阶乘问题[数论]

    题目描述 也许你早就知道阶乘的含义,N阶乘是由1到N相乘而产生,如: 12! = 1 x 2 x 3 x 4 x 5 x 6 x 7 x 8 x 9 x 10 x 11 x 12 = 479,001, ...

  5. luogu P4778 Counting swaps

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

  6. 洛谷P2398 GCD SUM [数论,欧拉筛]

    题目传送门 GCD SUM 题目描述 for i=1 to n for j=1 to n sum+=gcd(i,j) 给出n求sum. gcd(x,y)表示x,y的最大公约数. 输入输出格式 输入格式 ...

  7. 洛谷P2231 [HNOI2002]跳蚤 [数论,容斥原理]

    题目传送门 跳蚤 题目描述 Z城市居住着很多只跳蚤.在Z城市周六生活频道有一个娱乐节目.一只跳蚤将被请上一个高空钢丝的正中央.钢丝很长,可以看作是无限长.节目主持人会给该跳蚤发一张卡片.卡片上写有N+ ...

  8. 洛谷P1414 又是毕业季 [数论]

    题目传送门 又是毕业季 题目背景 “叮铃铃铃”,随着高考最后一科结考铃声的敲响,三年青春时光顿时凝固于此刻.毕业的欣喜怎敌那离别的不舍,憧憬着未来仍毋忘逝去的歌.1000多个日夜的欢笑和泪水,全凝聚在 ...

  9. 洛谷 - P1403 - 约数研究 - 数论

    https://www.luogu.org/problemnew/show/P1403 可以直接用线性筛约数个数求出来,但实际上n以内i的倍数的个数为n/i的下整,要求的其实是 $$\sum\limi ...

随机推荐

  1. Django ----- app 和 ORM的操作和介绍

    创建APP ORM 介绍 ORM的操作 说明一下 GET 和 POST 的区别: , GET ①获取一个页面 ②提交数据 数据显示在URL ?user=alex&pwd=alexdsb ,PO ...

  2. Mysql --数据的增删改

    插入数据 INSERT 更新数据 UPDATE 删除数据 DELETE 一. 在mysql管理软件中,可以通过SQL语句中的DML语言来实现数据的操作,包括 1.使用insert实现数据的插入 2.u ...

  3. 将DataTable转换为List<T>对象遇到问题:类型“System.Int64”的对象无法转换为类型“System.Int32”。

    可以利用反射将DataTable转换为List<T>对象:原始链接http://www.jb51.net/article/67386.htm 但是该方法在DataTable里某个字段类型是 ...

  4. vue-i18n国际化在data中切换不起作用

    vue-i18n是一个针对于vue的国际化插件,使用非常简单,具体使用方式看我细细道来. 实现方式 1. 下载包 npm install vue-i18n 2. 配置 在main.js文件中加入如下配 ...

  5. oracle查看执行最慢与查询次数最多的sql语句

    前言 在ORACLE数据库应用调优中,一个SQL的执行次数/频率也是常常需要关注的,因为某个SQL执行太频繁,要么是由于应用设计有缺陷,需要在业务逻辑上做出优化处理,要么是业务特殊性所导致.如果执行频 ...

  6. java----SAX解析XML

    XML: 可扩展标记语言 1.充当显示数据 2.储存数据 3.传输数据 SAX: 水电费 基于事假驱动,顺序读写,速度快 不能任意读取节点,灵活性差 解析时,占用内存小 import org.xml. ...

  7. C++11新特性(1)

    1.long long 类型 C++11新增了long long 和 unsigned long long 类型,为长整型和无符号长整型 long long 类型的数据占用8个字节(64位),取值范围 ...

  8. element-ui修改全局样式且只作用于当前页面

    1)修改组件的样式,但是只作用于当前页面,其他页面不受影响,做法有两种: 法一:使用关键字“/deep/” 1)在当前页面添加样式: <style lang="scss" s ...

  9. postgresql :: FATAL: could not write init file

    出现此错误,原因是磁盘空间被用尽.需要清理磁盘空间即可.

  10. table切换jquery插件 jQuery插件写法模板 流程

    通过$.extend()来扩展jQuery 通过$.fn 向jQuery添加新的方法 通过$.widget()应用jQuery UI的部件工厂方式创建 通过$.extend()来扩展jQuery $. ...