hdu 3923 Invoker(Polya定理)
题目链接:hdu 3923 Invoker
题意:
将n种元素,填在有m个位置的戒指上,问有多少种方案。
能旋转,翻转的算一种。
题解:
通过打表发现,对于x个位置的戒指,旋转i位的循环数为gcd(i,x);
然后对于翻转:考虑m的奇偶性,一共有m条对称轴。
然后就可以直接上快速幂解了。
1 #include<bits/stdc++.h> 2 #define F(i,a,b) for(int i=a;i<=b;++i) 3 using namespace std; 4 typedef long long ll; 5 6 const int N=10001,P=1e9+7; 7 int t,n,m,cas; 8 9 ll mypow(ll a,ll k){ 10 ll an=1; 11 while(k){ 12 if(k&1)an=an*a%P; 13 k>>=1,a=a*a%P; 14 } 15 return an; 16 } 17 18 int main(){ 19 cin>>t; 20 while(t--) 21 { 22 cin>>n>>m; 23 ll ans=0; 24 F(i,1,m)ans+=mypow(n,__gcd(i,m)); 25 if((m&1))ans=(ans+m*mypow(n,m/2+1))%P; 26 else ans=(ans+m/2*mypow(n,m/2+1)+m/2*mypow(n,m/2))%P; 27 ans=ans*mypow(2*m,P-2)%P; 28 cout<<"Case #"<<++cas<<": "<<ans<<endl; 29 } 30 return 0; 31 }