LFYZOJ 104 Counting Swaps
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>
#define ll long long
using namespace std;
const int MOD = 1e9 + 9, MAXN = 100005;
int T, n, num[MAXN], head[MAXN], nume, id[MAXN], hav[MAXN];
ll fac[MAXN], ni[MAXN];
struct edge{
int to, nxt;
}e[MAXN<<1];
void adde(int from, int to) {
e[++nume].to = to;
e[nume].nxt = head[from];
head[from] = nume;
}
ll quick_mod(ll a, ll k) {
if(!a) return 0ll;
if(k <= 0) return 1ll;
ll ans = 1;
while(k) {
if(k & 1ll) (ans *= a) %= MOD;
(a *= a) %= MOD;
k >>= 1;
}
return ans % MOD;
}
void dfs(int u, int cur) {
id[u] = cur;
for(int i = head[u]; i; i = e[i].nxt) {
int v = e[i].to;
if(!id[v]) dfs(v, cur);
}
}
int main() {
cin >> T;
fac[0] = 1;
for(int i = 1; i <= 100000; i++) fac[i] = fac[i - 1] * i % MOD;
ni[100000] = quick_mod(fac[100000], MOD - 2);
for(int i = 100000 - 1; i >= 0; i--) (ni[i] = ni[i + 1] * (i + 1)) %= MOD;
while(T--) {
cin >> n;
memset(head, 0, sizeof(head));
memset(id, 0, sizeof(id));
memset(hav, 0, sizeof(hav));
nume = 0;
for(int i = 1; i <= n; i++) scanf("%d", &num[i]), adde(i, num[i]);
int cnt = 0;
for(int i = 1; i <= n; i++) if(!id[i]) dfs(i, ++cnt);
for(int i = 1; i <= n; i++) hav[id[i]]++;
ll ans = 1ll;
for(int i = 1; i <= cnt; i++) (ans *= quick_mod(hav[i], hav[i] - 2)) %= MOD;
(ans *= fac[n - cnt]) %= MOD;
for(int i = 1; i <= cnt; i++) (ans *= ni[hav[i] - 1]) %= MOD;
printf("%lld\n", ans);
}
return 0;
}
LFYZOJ 104 Counting Swaps的更多相关文章
- CH3602 Counting Swaps
题意 3602 Counting Swaps 0x30「数学知识」例题 背景 https://ipsc.ksp.sk/2016/real/problems/c.html Just like yeste ...
- Counting swaps
Counting swaps 给你一个1-n的排列,问用最少的交换次数使之变为递增排列的方案数\(mod\ 10^9+7\),1 ≤ n ≤ 10^5. 解 显然最少的交换次数不定,还得需要找到最小交 ...
- 洛谷P4778 Counting swaps 数论
正解:数论 解题报告: 传送门! 首先考虑最终的状态是固定的,所以可以知道初始状态的每个数要去哪个地方,就可以考虑给每个数$a$连一条边,指向一个数$b$,表示$a$最后要移至$b$所在的位置 显然每 ...
- luogu P4778 Counting swaps
计数套路题?但是我连套路都不会,,, 拿到这道题我一脸蒙彼,,,感谢@poorpool 大佬的博客的指点 先将第\(i\)位上的数字\(p_i\)向\(i\)连无向边,然后构成了一个有若干环组成的无向 ...
- lfyzoj104 Counting Swaps
问题描述 给定你一个 \(1 \sim n\) 的排列 \(\{p_i\}\),可进行若干次操作,每次选择两个整数 \(x,y\),交换 \(p_x,p_y\). 请你告诉穰子,用最少的操作次数将给定 ...
- luoguP4778 Counting swaps
题目链接 题解 首先,对于每个\(i\)向\(a[i]\)连边. 这样会连出许多独立的环. 可以证明,交换操作不会跨越环. 每个环内的点到最终状态最少交换步数是 \(环的大小-1\) 那么设\(f[i ...
- P4778 Counting Swaps 题解
第一道 A 掉的严格意义上的组合计数题,特来纪念一发. 第一次真正接触到这种类型的题,给人感觉好像思维得很发散才行-- 对于一个排列 \(p_1,p_2,\dots,p_n\),对于每个 \(i\) ...
- Java集合---Array类源码解析
Java集合---Array类源码解析 ---转自:牛奶.不加糖 一.Arrays.sort()数组排序 Java Arrays中提供了对所有类型的排序.其中主要分为Prim ...
- Java Arrays.sort源代码解析
前提: 当用到scala的sortWith,发现: def sortWith(lt: (A, A) ⇒ Boolean): List[A] // A为列表元素类型 根据指定比较函数lt进行排序,且排序 ...
随机推荐
- sql server 定时备份 脚本
) DECLARE @date DATETIME SELECT @date = GETDATE() SELECT @filename = 'G:\backup\NewPlulishSQL-' + CA ...
- 初学redis,redis基本数据类型
String: 1. set key value 2. get key 3. del key 4. strlen key 5. getset key value 修改键值对 6. getrange ...
- Mac brew 安装amp环境
|首先加入Homebrew官方的几个软件源 $ brew tap homebrew/dupes $ brew tap homebrew/versions $ brew tap homebrew/php ...
- python3 完全平方数(循环)
题目 一个整数,它加上100后是一个完全平方数,再加上168又是一个完全平方数,请问该数是多少? 代码: for i in range(1,85): if 168 % i == 0: j = 168 ...
- Relu的缺点
Relu不适合梯度过大的的输入 Relu是我们在训练网络时常用的激活函数之一(对我而言没有之一).然而最近发现Relu太脆弱了,经常由于输入的函数梯度过大导致网络参数更新后,神经元不再有激活功能.特别 ...
- manjaro linux没有ll等命令的解决办法
编辑~/.bashrc, 添加alias 如下 vim ~/.bashrc设置别名. 添加如下行 alias ll='ls -alF' alias la='ls -A' alias vi='vim' ...
- LeetCode(219) Contains Duplicate II
题目 Given an array of integers and an integer k, find out whether there are two distinct indices i an ...
- CodeForce:16C-Monitor
传送门:http://codeforces.com/problemset/problem/16/C Monitor time limit per test0.5 second memory limit ...
- 浅谈内核的Makefile、Kconfig和.config文件
Linux内核源码文件繁多,搞不清Makefile.Kconfig..config间的关系,不了解内核编译体系,编译修改内核有问题无从下手,自己写的驱动不知道怎么编进内核,不知道怎么配置内核,这些问题 ...
- 关于C#Debug和Release
在程序调试时的debug和release 网上有如下的描述:Debug 通常称为调试版本,它包含调试信息,并且不作任何优化,便于程序员调试程序.Release 称为发布版本,它往往是进行了各种优化,使 ...