Necklace and bracelet Uva 10294 - Polya Theorem

The meaning of problems

Necklaces and bracelets are made of a plurality of annular beads strung jewelry, except that the bracelet can be reversed, but not the necklace.

N-input integer $ $ $ t $, and, with the number of output color $ t $ $ $ n-beads can be made into a necklace and bracelet. ($ 1 \ leq n \ leq 50, 1 \ leq t \ leq 10 $).

analysis

There are two replacement here, that rotate and flip, only one necklace, and bracelet have both.

Rotation: If the spacing is rotated counterclockwise $ I $ beads, the $ 0, i, 2i, ... $ constitute one cycle (when the mold is greater than $ $ $ n-n-$), this cycle has $ n / gcd (i, n) $ elements. By symmetry, the length of each cycle are equal, it is $ gcd (i, n) $ cycles. The total number of fixed point is replaced $ a = \ sum_ {t = 0} ^ {n-1} t ^ {gcd (i, n)} $.

Flip:

When the n-$ $ is odd, there is an axis of symmetry $ $ n-pieces, each forming an axis of symmetry $ (n-1) / 2 $ a length of 2 cycles and a length of cycle 1, i.e., $ (n + 1) / $ 2 cycles. The total number of such substitutions Fixed point $ b = nt ^ {\ frac {n + 1} {2}} $.

When the n-$ $ is an even number, two axis of symmetry. Symmetry axis passing through the beads are $ n / 2 $ strips, each formed $ n / 2-1 $ of each cycle of length 2 and two lengths of the loop 1; a symmetry axis does not pass through the beads are $ n / 2 $ strips, each formed $ n / 2 $ 2 cycles of length. The total number of such substitutions Fixed point $ b = \ frac {n} {2} (t ^ {n / 2 + 1} + t ^ {n / 2}) $.

The Polya theorem, the number of equivalence classes is not equal to the average of the total point. Therefore, the total number of necklace $ a / n $, bracelets Total $ (a + b) / 2n $.

#include<bits/stdc++.h>
using namespace std;

typedef long long ll;
const int maxn = 50+5;
ll p[maxn];

int gcd(int a, int b)
{
    return b == 0 ? a : gcd(b, a%b);
}

int main()
{
    int n, t;
    while(scanf("%d%d", &n, &t) == 2 && n)
    {
        p[0]=1;
        for(int i = 1;i <= n;i++)  p[i] = p[i-1] * t;
        ll a = 0;
        for(int i = 0;i < n;i++)  a += p[gcd(i, n)];
        ll b = 0;
        if(n & 1)  b = n * p[(n+1)/2];
        else  b = n/2 * (p[n/2 + 1] + p[n/2]);
        printf("%lld %lld\n", a/n, (a+b)/(2*n));
    }
    return 0;
}

 

Guess you like

Origin www.cnblogs.com/lfri/p/11455667.html