poj-1286&&2409-polya定理

来源:互联网 发布:梦里花落知多少李茉莉 编辑:程序博客网 时间:2024/05/18 23:53

对于统计有多少个不同的解决方案的问题的求法:
对于每一种转变,有多少种不同的解决方案,这些解决方案的平均值即为最终答案。

比如说从3种珠子里选5颗制作手链,求有多少种不同的手链。

对于手链来说,旋转和翻转而成的手链是相同的。

旋转:

5颗珠子一共有5种旋转方式,分别是旋转i颗(0<=i<5)。

对于每种旋转,共有3^(gcd(i,5))种解决方案。

a=sum(3^(gcd(i,5)))(0<=i<5)

翻转:
奇数个珠子共有5个翻转方式。

对于每种翻转,共有3^((5+1)/2)种解决方案。

b=n*3^((5+1)/2)

所以最终的答案为(a+b)/n

2409的代码:

#include <stdio.h>#include<string.h>#include<iostream>#include<algorithm>#include<stdlib.h>#include<math.h>#define LL long longusing namespace std;LL pows[101];int t;int gcd(int n,int m){    if(n<m) swap(n,m);    if(m==0)return n;    return n%m==0?m:gcd(m,n%m);}void init(){    pows[0]=1;    for(int i=1;i<101;i++)    {        pows[i]=pows[i-1]*t;    }}int main(){    LL sum;    int n,i;    while(~scanf("%d%d",&t,&n)&&(n||t))    {        init();        if(n==0)        {            cout<<"0"<<endl;            continue;        }        sum=0;        for(i=0;i<n;i++)sum+=pows[gcd(i,n)];        if(n%2)        {            sum+=n*pows[(n+1)/2];        }        else        {            sum+=(n/2)*(pows[n/2]+pows[n/2+1]);        }        sum=sum/2/n;        cout<<sum<<endl;    }    return 0;}


0 0