poj 1721 CARDS(置换群的幂运算)

Problem Link

CARDS
大意,给你一个长为n的奇数循环 T ,求 T2s=T .求置换 T ;

Analysis

这个题目是非常典型的,在《置换群的幂运算的应用与研究》,潘振浩的论文里面有描述。
有两种方法:
1。我们知道对于任意一个循环 T 中存在一个 kn ,使得 Tk=T ,对于循环 T 用暴力 n2 找到循环节 k ,然后再用做k-s%k doubleshuffle2 (2^s,n) = 1$所以可以开方。设数组a[] = T,a’[] = T’,(a[0] = 1)(最小元),则a’[i] = a[(i*(2^m)) % n]
下面给出两种代码
法1:

Source Code

Problem: 1721       User: taotao
Memory: 756K        Time: 32MS
Language: G++       Result: Accepted
Source Code
#include
#include
#include
#include

using namespace std;

const int maxn = 1100;
int n,s;
int a[maxn],b[maxn],c[maxn];

void permitation(const int *x,int *y)
{
    for(int  i =1 ; i<=n  ; ++i)
        y[i] = x[x[i]];
}

bool check(int* x,int *y)
{

    int i=1 ;
    while(i<=n)
    {
        if(x[i]!=y[i])return false;
        i++;
    }
    return true;
}

int main()
{

    while(cin>>n>>s)
    {
        for(int i=1 ; i<=n ; ++i)scanf("%d",&a[i]);
        memcpy(c,a,sizeof(a));
        int cnt = 0;
        while(1)
        {
            cnt++;
            permitation(c,b);
            if(check(a,b))break;
            memcpy(c,b,sizeof(b));
        }
        s%=cnt;
        s = cnt-s;

        while(s--)
        {
            permitation(a,b);
            memcpy(a,b,sizeof(b));
        }
        for(int i =1 ; i<=n ; ++i)
            cout<

法2:

Source Code

Problem: 1721       User: zouzhitao
Memory: 756K        Time: 16MS
Language: G++       Result: Accepted
Source Code
#include
#include
#include
#include
#include

using namespace std;
const int maxn = 1111;

int a[maxn],tmp[maxn],ans[maxn],cir[maxn];

int n,s;

int pow_mod(int x,int n,int mod)
{
    int res = 1;
    while(n)
    {
        if(n&1)res = res*x%mod;
        x = x*x%mod;
        n>>=1;
    }
    return res;
}

void solve()
{
    int cnt = 0,p;
    cir[cnt++] = p = 1;
    while(a[p]!=1)
    {
        cir[cnt++] = a[p];
        p = a[p];
    }
    int k = pow_mod(2,s,n);
    for(int i =0 ; i//for(int i=0 ; i
    for(int i=0 ; i1 ; i++)
        ans[tmp[i]] = tmp[i+1];
    ans[tmp[n-1]] = tmp[0];
}


int main()
{
    while(cin>>n>>s)
    {
        for(int i=1 ; i<=n ; ++i)scanf("%d",&a[i]);
        solve();
        for(int i=1 ; i<=n ; ++i)cout<

你可能感兴趣的:(算法刷题)