码迷,mamicode.com
首页 > 其他好文 > 详细

poj1286 polya计数法

时间:2016-02-27 23:22:23      阅读:209      评论:0      收藏:0      [点我收藏+]

标签:

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

  首先我们可以知道这个置换群中有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;
}

 

poj1286 polya计数法

标签:

原文地址:http://www.cnblogs.com/xingxing1024/p/5223753.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!