poj1286 Necklace of Beads

本文探讨了一个经典的组合数学问题,即使用三种颜色的珠子串成项链的不同方式数量的计算方法,考虑旋转和翻转后的等价性。通过Polya定理进行解答,并提供了一段C++实现代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

http://www.elijahqi.win/archives/3391
Description

Beads of red, blue or green colors are connected together into a circular necklace of n beads ( n < 24 ). If the repetitions that are produced by rotation around the center of the circular necklace or reflection to the axis of symmetry are all neglected, how many different forms of the necklace are there?

这里写图片描述
Input

The input has several lines, and each line contains the input data n.
-1 denotes the end of the input file.
Output

The output should contain the output data: Number of different forms, in each line correspondent to the input data.
Sample Input

4
5
-1
Sample Output

21
39
Source

Xi’an 2002
题意:给三种颜色的珠子串项链 允许翻转允许旋转且旋转或者翻转之后如果相同认为是一种方案
直接套用polya公式即可
首先考虑旋转操作 置换最多有n种否则就又变成原来的样子了 考虑其中旋转i个单位的循环节个数是多少
循环节长度 lcm(i,n)i l c m ( i , n ) i 又因为每个循环节都相同 所以个数就是 nlcm(i,n)i n l c m ( i , n ) i
然后把lcm用gcd什么替换一下即可得到答案为gcd(i,n)
然后翻转的情况 针对n为奇数 考虑固定一个点为对称点那么(n-1)中都是循环节+1(自己也是循环节
n为偶数情况 考虑分割时候恰好切在两点上 循环节个数 (n2)2+2 ( n − 2 ) 2 + 2
或者恰好在两点之间循环节个数 n2 n 2

#include<cstdio>
#include<cctype>
#include<algorithm>
#define ll long long
using namespace std;
inline char gc(){
    static char now[1<<16],*S,*T;
    if (T==S){T=(S=now)+fread(now,1,1<<16,stdin);if (T==S) return EOF;}
    return *S++;
}
inline int read(){
    int x=0,f=1;char ch=gc();
    while(!isdigit(ch)) {if (ch=='-') f=-1;ch=gc();}
    while(isdigit(ch)) x=x*10+ch-'0',ch=gc();
    return x*f;
}
inline int gcd(int x,int y){return (!y)?x:gcd(y,x%y);}
inline ll ksm(ll b,int t){static ll tmp;
    for (tmp=1;t;b=b*b,t>>=1) if(t&1) tmp=tmp*b;return tmp;
}
int main(){
    freopen("poj1286.in","r",stdin);
    while(1){
        int n=read();if (n==-1) return 0;
        if (n==0) {puts("0");continue;}ll ans=0;
        for (int i=0;i<n;++i) ans+=ksm(3,gcd(i,n));
        if (n&1) ans+=(ll)n*ksm(3,(n>>1)+1);
        else{
            ans+=n/2*ksm(3,(n-2)/2+2);
            ans+=n/2*ksm(3,n>>1);
        }ans>>=1;ans/=n;
        printf("%lld\n",ans);
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值