昨天入手了Richard A.Brualdi的《组合数学》(第五版),粗粗翻了一下,发现前几章排列组合计数什么的高中搞MO的时候学过了,于是水了几题之后,直接开始看最后一章polya计数,啃了一整天差不多算是粗粗过了一遍。还是有许多地方理得不是很清晰,之后再巩固吧。
水个入门题先,poj2409。
题意:长度为n的圆环,用c种颜色染色,问有多少种不同的染色法。其中,可通过旋转和翻转得到的视为同一种。
典型的polya入门吧,思路懒得写了,去看上面提到的那本书吧,讲的很详细了。代码如下:
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
typedef long long ll;
ll c,n;
ll gcd(ll a,ll b)
{
if(b==0)return a;
else return gcd(b,a%b);
}
ll f(ll n)
{
ll ans=1;
for(ll i=1;i<=n;i++)
ans*=c;
return ans;
}
int main()
{
while(scanf("%lld%lld",&c,&n)&&n!=-1)
{
if(n==0&&c==0)break;
if(n==0||c==0){printf("0\n");continue;}
ll sum=0;
sum+=f(n);
for(ll i=1;i<=n-1;i++)
{
sum+=f(gcd(i,n));
}
if(n%2==1)
{
sum+=n*f(n/2+1);
}
else
{
sum+=n/2*f(n/2);
sum+=n/2*f(n/2+1);
}
ll ans=sum/n/2;
printf("%lld\n",ans);
}
return 0;
}
这三天看似认真,其实水的成分偏多,也就学了矩阵快速幂的写法和粗读一遍polya定理,以后除了暑假集训也很少这么集中的学习时间了,时不我待啊。归结起来还是智商不够,看难一点的东西还是很吃力。最近计划学组合和数论(我的MO情结啊),各种考试又来了,唉。