Pinely Round 2 (Div. 1 + Div. 2) G. Swaps(组合计数)

题目

给定一个长度为n(n<=1e6)的序列,第i个数ai(1<=ai<=n),

操作:你可以将当前i位置的数和a[i]位置的数交换

交换可以操作任意次,求所有本质不同的数组的数量,答案对1e9+7取模

思路来源

力扣群 潼神

心得

感觉已经说的很详尽了,甚至没什么需要补充的地方...

不难发现,自环的情况和>=2的环的情况是统一的,所以dfs找环即可

组合题更多的是一种无从下手的感觉,需要多培养手玩性质的能力

比如,发现a->b->c到a->c,b->b这个性质,然后再着手计数

代码

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;
#define rep(i,a,b) for(int i=(a);i<=(b);++i)
#define per(i,a,b) for(int i=(a);i>=(b);--i)
typedef long long ll;
typedef double db;
typedef pair<ll,int> P;
#define fi first
#define se second
#define pb push_back
#define dbg(x) cerr<<(#x)<<":"<<x<<" ";
#define dbg2(x) cerr<<(#x)<<":"<<x<<endl;
#define SZ(a) (int)(a.size())
#define sci(a) scanf("%d",&(a))
#define pt(a) printf("%d",a);
#define pte(a) printf("%d\n",a)
#define ptlle(a) printf("%lld\n",a)
#define debug(...) fprintf(stderr, __VA_ARGS__)
typedef unsigned ui;
//typedef __uint128_t L;
typedef unsigned long long L;
typedef unsigned long long ull;
const int N=1e6+10,mod=1e9+7;
int n,v,to[N],deg[N];
vector<int>e[N];
int stk[N],c,ans=1;
bool vis[N],in[N];
void dfs(int u){
	if(!u)return;
	stk[++c]=u;
	in[u]=1;
	vis[u]=1;
	int v=to[u];
	if(in[v]){//环的情况 统一了自环的情况
		int res=1,sub=0;
		while(c){
			int w=stk[c--];in[w]=0;
			res=1ll*res*(deg[w]+1)%mod;
			sub=(sub+deg[w])%mod;
			if(w==v)break;
		}
		res=(res+mod-sub)%mod;
		ans=1ll*ans*res%mod;
	}
	if(!vis[v])dfs(v);
}
int main(){
	sci(n);
	rep(i,1,n){
		sci(v);
		to[i]=v;
		deg[v]++;
	}
	rep(i,1,n){
		if(!vis[i]){
			dfs(i);
		}
		while(c){
			int w=stk[c--];in[w]=0;
			ans=1ll*ans*(deg[w]+1)%mod;
		}
	}
	printf("%d\n",ans);
	return 0;
}
相关推荐
闻缺陷则喜何志丹12 小时前
【C++组合数学】P8106 [Cnoi2021] 数学练习|普及+
c++·数学·洛谷·组合数学
l1t5 天前
利用DeepSeek计算abcde五人排成一队,要使c在ab 之间,有几种排法
人工智能·组合数学·deepseek
闻缺陷则喜何志丹8 天前
【组合数学】P9418 [POI 2021/2022 R1] Impreza krasnali|普及+
c++·数学·组合数学
Tisfy15 天前
LeetCode 3577.统计计算机解锁顺序排列数:脑筋急转弯(组合数学)
算法·leetcode·题解·组合数学·脑筋急转弯
Tisfy15 天前
LeetCode 3583.统计特殊三元组:哈希表计数
算法·leetcode·散列表·题解·哈希表·计数
资深web全栈开发21 天前
LeetCode 3625. 统计梯形的数目 II
算法·leetcode·组合数学
资深web全栈开发23 天前
LeetCode 3623. 统计梯形的数目 I
算法·leetcode·职场和发展·组合数学
HAH-HAH3 个月前
【蓝桥杯 2024 国 Java A】粉刷匠小蓝
c++·学习·数学·算法·职场和发展·蓝桥杯·组合数学
Beau_Will1 年前
牛客练习赛132
c++·算法·贪心算法·组合数学·取模
Sasakihaise_1 年前
LeetCode 3208. 交替组 II
算法·leetcode·计数·循环链表