zoukankan      html  css  js  c++  java
  • 2020牛客暑期多校训练营(第二场) J-Just Shuffle【置换群】

    传送门

    题意

    已知({1,2,...,n})按照(P)经过(k)次变化之后得到(A),现在给定(A)(k),求({1,2,...,n})按照(P)经过(1)次变化之后的结果(B)

    题解

    主要的知识点是置换群,当然我一点都不了解,所以这道题直接GG。
    可以得知,(B^k=A),根据置换群与逆元可知,(A^{k^{-1}}=B)。设(A)中所有环是(r_1,r_2,...,r_m),本来(k^{-1})应该是(lcm{|r_1|,|r_2|,...,|r_m|})下的逆元,但其实可以对每个环分开考虑,所以对于每个环(r_i),求出(k)在模(|r_i|)下的逆元(inv_i),然后对环上每个点变换(inv_i)次就行了。

    代码

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long LL;
    const int N=1e5+10;
    int n,a[N],ans[N],vis[N],k;
    vector<int> vec;
    
    void dfs(int u){
    	if(vis[u]) return;
    	vis[u]=1;
    	vec.push_back(u);
    	dfs(a[u]);
    }
    
    int main(){
    	scanf("%d%d",&n,&k);
    	for(int i=1;i<=n;i++) scanf("%d",&a[i]);
    	for(int w=1;w<=n;w++){
    		if(vis[w]) continue;
    		vec.clear();
    		dfs(w);
    		int siz=vec.size(),inv;
    		for(int i=1;i<=siz;i++)if(1ll*k*i%siz==1) inv=i;
    		for(int i=0;i<siz;i++) ans[vec[i]]=vec[(i+inv)%siz];
    	}
    	for(int i=1;i<=n;i++) printf("%d ",ans[i]);
    	return 0;
    }
    
  • 相关阅读:
    洛谷P1199三国游戏
    Cracking the Coding Interview 6.2
    Cracking the Coding Interview 5.2
    Cracking the Coding Interview 5.7
    洗牌算法
    字符串排列组合问题
    指针作为形参
    KMP算法代码
    搜索二叉树
    面试题集锦
  • 原文地址:https://www.cnblogs.com/BakaCirno/p/13384067.html
Copyright © 2011-2022 走看看