zoukankan      html  css  js  c++  java
  • 2020牛客暑期多校训练营(第二场)Just Shuffle

    题目链接

    https://ac.nowcoder.com/acm/contest/5667/J

    题目大意

    给你一个置换 B , 要求找到置换 P 使得 $PA^{k}=B$ , 其中 A 为 P 的置换规则

    解题思路 

    置换是满足逆元关系的

    $P=PA^{k}A^{-k}=BA^{-k}$

    一个置换的某个位置的某个数在改变了一定次数后一定会变回它自己,即每个位置都属于某个环中 

    我们设某个环的大小为 len , 那么这个环中的数置换的次数为 k % len

    我们设 t = k % len , 那么根据 t * t^-1 = 1 , 我们只要让这个环中的每个数再改变 t^-1次

    就可以回到初始的位置 , 而 t^-1 即是 k 在 % len 下的逆元

    AC_Code

    #include<bits/stdc++.h>
    #define int long long
    #define ll long long 
    using namespace std;
    ll exgcd1(ll a,ll b,ll &x,ll &y){if(!b){x=1,y=0;return a;}ll t=exgcd1(b,a%b,y,x);y-=a/b*x;return t;}
    ll get_inv(ll a,ll mod){ll x,y;ll d=exgcd1(a,mod,x,y);return d==1?(x%mod+mod)%mod:-1;}
    const int N = 3e5 + 10;
    int a[N] , vis[N] , ans[N];
    vector<int>vec;
    signed main()
    {
        ios::sync_with_stdio(false) , cin.tie(0) , cout.tie(0);
        int n , k;
        cin >> n >> k ;
        for(int i = 1 ; i <= n ; i ++) cin >> a[i];
        for(int i = 1 ; i <= n ; i ++)
        {
            if(vis[i]) continue ;
            vec.clear();
            vec.push_back(i) , vis[i] = 1;
            int now = a[i];
            while(now != i)
            {
                vec.push_back(now) , vis[now] = 1;
                now = a[now];
            }
            int sz = vec.size() , ny = get_inv(k , sz);
            for(int j = 0 ; j < sz ; j ++) ans[vec[j]] = vec[(j + ny) % sz];
        }
        for(int i = 1 ; i <= n ; i ++) cout << ans[i] << " ";
        cout << '
    ';
        return 0;
    }
  • 相关阅读:
    [ZZ]终极期望
    推荐一部好电影
    读书笔记:《Java2 教程》(五)
    波音飞机的消息
    雪景
    [ZZ]候捷谈Java反射机制
    关于J2ME开发的感想(20060505更新)
    读书笔记:《Java2 教程》(七)
    读书笔记:《Java2 教程》(六)
    注册了Bloglines
  • 原文地址:https://www.cnblogs.com/StarRoadTang/p/13345864.html
Copyright © 2011-2022 走看看