poj1286 polya计数法

  这个题的意思是是给你一串珠子, 珠子可以绕中心旋转, 也可以轴对称, 问用三种颜色染这一串珠子有几种情况?

  首先我们可以知道这个置换群中有2n个元素, 当n为奇数的时候为n*3^(n/2+1),  当n为偶数的时候分两种情况n/2*(3^(n/2)+3^(n^2+1)), 当旋转的时候有

sigma(3^d*phi(n/d))  d|n, 代码如下:

#include <iostream>
#include <algorithm>
#include <vector>

using namespace std;
typedef long long LL;
int n;

LL pow(LL A, LL B)
{
    LL res = 1;
    while(B > 0)
    {
        if(B%2==1)
            res = res*A;
        A = A*A;
        B = B/2;
    }
    return res;
}

vector<int> divisor(int n)   //获取n的约数因子
{
    vector<int> res;
    for(int i=1; i*i<=n; i++)
    {
        if(n%i == 0)
        {
            res.push_back(i);
            if(i!=n/i)
                res.push_back(n/i);
        }
    }
    return res;
}

int pi[100], npi;
void prime_factor(int n)
{
    npi = 0;
    for(int i=2; i*i<=n; i++)
    {
        if(n%i==0)
        {
            pi[npi++] = i;
            while(n%i==0) n/=i;
        }
    }
    if(n!=1) pi[npi++] = n;
}

LL solve(int n)
{
    vector<int> div;
    div = divisor(n);
    prime_factor(n);
    LL res = 0;
    for(int i=0; i<div.size(); i++)
    {
        LL euler = div[i];
        for(int j=0; j<npi; j++)
            if(div[i]%pi[j]==0)
            euler = euler/pi[j]*(pi[j]-1);
        res += pow(3, n/div[i])*euler;
    }
    if(n&1) res += n*pow(3, n/2+1);
    else res += (pow(3, n/2)+pow(3, n/2+1))*(n/2);
    return res/(2*n);
}

int main()
{
    while(cin>>n)
    {
        if(n==-1) break;
        if(n==0)
        {
            cout<<0<<endl;
            continue;
        }
        LL res = solve(n);
        cout<<res<<endl;
    }
    return 0;
}

 

转载于:https://www.cnblogs.com/xingxing1024/p/5223753.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值