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进行排序,且排序 ...
随机推荐
- 01windows常用命令及批处理
1. 概述 复制内容:右键弹出快捷菜单,选择"标记(K)",然后选中所需要的内容,然后右键即可 粘贴内容:右键弹出快捷菜单,选择"粘贴(P)" 命令参数的路径: ...
- linux关于任务计划
1.一次性任务计划:at 1)添加 在18:16时候重启服务器 at 18:16 >at init 6 >at ctrl+d2)查看 atq 1 Mon Aug 20 21:09:00 2 ...
- python numpy复制array
numpy快速复制array 前段时间想到一个算法,需要实现array的自我复制,直接上代码,两种复制方式, 整体复制 a=[[10,10,50,50],[10,10,40,50]] np.tile( ...
- MongoDB学习-->Gridfs分布式存储&DBRef关联查询
mongodb自带的一个分布式文件系统 fs.files _id filename md5 size uploaddate contenttype metadata {"user_id&qu ...
- Android 标题栏(2)
本文来自网易云社区 作者:孙圣翔 添加ActionProvider 1.在menu菜单中添加app:actionProviderClass属性: <item android:id=&qu ...
- KVO And KVC
http://www.cocoachina.com/industry/20140224/7866.html
- 27、android log日志
一.记住 加写sd卡权限 二.代码 package com.example.logtest; import java.io.File; import java.io.IOException; impo ...
- 编译安装solr
1, 获取安装包 wget http://download.oracle.com/otn-pub/java/jdk/8u112-b15/jdk-8u112-linux-x64.rpm wget htt ...
- 为什么在header 和 session 之前不能有输出
1.在header输出之前有输出内容的话,就会造成对header的错误理解(尽管现在已经能容错了),例如不是满足“keyword: value\n”的格式还好,直接错误了,但是满足“keyword: ...
- 如何正确遍历删除List中的元素
遍历删除List中的元素有很多种方法,当运用不当的时候就会产生问题.下面主要看看以下几种遍历删除List中元素的形式: 1.通过增强的for循环删除符合条件的多个元素 2.通过增强的for循环删除符合 ...