这个问题很意思
奇数 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)是一样的),则认为他们是一样的)
给你n种卡牌(数量无限),将其摆成长度为m的圆环的方案数。
这时古yu一脸茫然,大哭特苦不能守护白起了。古yu希望你能帮助他解决这个问题去守护白起。
输入描述:
第一行一个t(0<t<=500) 接下来t行,每行俩个正整数n,m(1<=n,m<=10000)
输出描述:
一个答案加换行(答案可能很大,所以取模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<iostream> 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; }
未来的我一定会感谢正在努力的现在的我!