您的位置:首页 > 其它

HDU 3923 Invoker(polya定理模版题)

2016-09-02 14:15 417 查看
这题就是问你n个颜色,构成长度m的项链,有几种

手镯是只能旋转,不可翻转的,项链可以旋转也可以翻转

旋转有n个不动点,翻转也有n个,所以最后是除以2n

考虑旋转的情况,可以旋转0,1,2,3,4...m−1格,然而构成的循环有多少个呢

因为同一个循环,里面要涂一样的颜色,才能是相同

旋转i格,构成的循环个数是gcd(i,m),然后颜色就是ngcd(i,m)

翻转的话就是考虑m的奇偶,根据奇偶分类,然后翻转里的循环,就是翻转后,互相换的那两个

所以翻转后互相变换的两个要颜色一样,算一下有多少个循环就行了

代码:

#include <map>
#include <set>
#include <stack>
#include <queue>
#include <cmath>
#include <string>
#include <vector>
#include <cstdio>
#include <cctype>
#include <cstring>
#include <sstream>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#pragma comment(linker,"/STACK:102400000,102400000")

using namespace std;
#define   MAX           10005
#define   MAXN          1000005
#define   maxnode       205
#define   sigma_size    2
#define   lson          l,m,rt<<1
#define   rson          m+1,r,rt<<1|1
#define   lrt           rt<<1
#define   rrt           rt<<1|1
#define   middle        int m=(r+l)>>1
#define   LL            long long
#define   ull           unsigned long long
#define   mem(x,v)      memset(x,v,sizeof(x))
#define   lowbit(x)     (x&-x)
#define   pii           pair<int,int>
#define   bits(a)       __builtin_popcount(a)
#define   mk            make_pair
#define   limit         10000

//const int    prime = 999983;
const int    INF   = 0x3f3f3f3f;
const LL     INFF  = 0x3f3f;
//const double pi    = acos(-1.0);
const double inf   = 1e18;
const double eps   = 1e-9;
const LL     mod   = 1e9+7;
const ull    mx    = 133333331;

/*****************************************************/
inline void RI(int &x) {
char c;
while((c=getchar())<'0' || c>'9');
x=c-'0';
while((c=getchar())>='0' && c<='9') x=(x<<3)+(x<<1)+c-'0';
}
/*****************************************************/

LL fact[MAX];

int gcd(int a,int b){
if(!b) return a;
return gcd(b,a%b);
}

LL qpow(LL a,LL n){
LL ans=1;
while(n){
if(n&1) ans=ans*a%mod;
a=a*a%mod;
n>>=1;
}
return ans;
}
int main(){
//freopen("in.txt","r",stdin);
int t,kase=0;
cin>>t;
while(t--){
int n,m;
cin>>m>>n;
fact[0]=1;
kase++;
for(int i=1;i<=10000;i++) fact[i]=fact[i-1]*m%mod;
LL a=0;
for(int i=0;i<n;i++){
a+=fact[gcd(i,n)];
if(a>=mod) a-=mod;
}
LL b=0;
if(n%2==1){
b=n*fact[(n+1)/2]%mod;
}
else b=(n/2)*(fact[n/2]+fact[n/2+1])%mod;
printf("Case #%d: ",kase);
cout<<(a+b)*qpow(2*n,mod-2)%mod<<endl;
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: