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 }
View Code

 

posted @ 2017-06-23 19:58  bin_gege  阅读(124)  评论(0编辑  收藏  举报