版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/yz467796454/article/details/82945483
题目链接:B - Buildings
Sample Input 1 Sample Output 1
1 3 1 1
Sample Input 2 Sample Output 2
2 5 2 209728
题意:一个房子,正m边形,每一面墙n*n的格子,c个颜色可以选择,旋转重合算一个方案,问有几种涂色方案
思路:一面墙的不同方案数为c^(n*n),那么问题转化为,这些不同的方案数,涂色,旋转重合算一个方案。所以用polya计数法,可以看这个博客菜鸟系列——polya计数法 ,这里的项链例题是可以翻转的,而本题翻转不算同一个方案
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<iostream>
#include<string>
#include<map>
#include<vector>
using namespace std;
#define maxn 600005
typedef long long ll;
const ll mod=1e9+7;
ll mo(ll a,ll pp){
if(a>=0&&a<pp)return a;
a%=pp;
if(a<0)a+=pp;
return a;
}
ll powmod(ll a,ll b,ll pp){
ll ans=1;
for(;b;b>>=1,a=mo(a*a,pp)){
if(b&1)ans=mo(ans*a,pp);
}
return ans;
}
ll inv1(ll b){
return powmod(b,mod-2,mod);
}
ll gcd(ll x,ll y){
return y?gcd(y,x%y):x;
}
int main(){
ll n,m,c;
scanf("%lld%lld%lld",&n,&m,&c);
ll ans=powmod(c,n*n,mod);
ll sum=0;
for(int i=1;i<=m;i++){
sum=(sum+powmod(ans,gcd(m,i),mod))%mod;
}
sum=sum*inv1(m)%mod;
printf("%lld\n",sum);
return 0;
}