n方格染色问题

 这个问题很意思

奇数 m*n^(m/2+1)  偶数  m/2*n^(m/2+1) + m/2*n^(m/2 )

:ans += gcd(n,i)   不同i不同数的求和

: 最后  :可能是死的,看了好久没看懂 ans*pow(m*2%M,M-2)%M

 

题目描述

最近古yu迷上了《恋与制作人》,天天嚷嚷着白起我老公(死gay死gay的),白起又向古yu提出了一个问题:
给你n种卡牌(数量无限),将其摆成长度为m的圆环的方案数。
(如果这个环可以通过若干次旋转或者反方向读((abc)(cba)是一样的),则认为他们是一样的)
这时古yu一脸茫然,大哭特苦不能守护白起了。古yu希望你能帮助他解决这个问题去守护白起。

输入描述:

第一行一个t(0 
   

输出描述:

一个答案加换行(答案可能很大,所以取模1000000007)
示例1

输入

2
3 4
1 2

输出

21
1

说明

对于第一个样例有21种不同的方法
/ aaaa / aaab / aaac / aabb / aabc / aacc / abab /
/ abac / abbb / abbc / abcb / abcc / acac / acbc /
/ accc / bbbb / bbbc / bbcc / bcbc / bccc / cccc

#include
using namespace std ;
typedef long long ll ;
#define f(i,l,r) for(int i=l;i<=r;++i)
#define g(i,l,r) for(int i=l;i>=r;--i)
  ll M = 1e9+7;
ll gcd(ll a,ll b){
    return b?gcd(b,a%b):a;
}
ll pow (ll a ,ll b){
	ll  ans =1;
	while(b){
		if(b%2==1)
			ans =ans*a%M;
		a=a*a%M;
		b>>=1;
	}
	return ans;
}

ll slove(ll n,ll m)
{
	ll ans=0;
	if(m & 1) ans=m*pow(n,m/2+1)%M;
	else ans=((m/2*pow(n,m/2))%M+(m/2*pow(n,m/2+1))%M)%M;
	for(int i=0;i<m;++i) ans=(ans+pow(n,gcd(m,i)))%M;
	ans =  ans*pow(m*2%M,M-2)%M ;
	return ans ;
} 

int main(){
	ll t ,a,b;
	cin>>t ;
	while(t--){
		cin>>a>>b;
		cout<<slove(a,b)<<endl;
	}


	return 0;
}

未来的我一定会感谢正在努力的现在的我!


你可能感兴趣的:(Newcoder)