gym-101873B Buildings(polya计数)

版权声明:本文为博主原创文章,未经博主允许不得转载。 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;
}

猜你喜欢

转载自blog.csdn.net/yz467796454/article/details/82945483