【Polya】 hdu 3923(SummerIII Y)

xiaoxiao2021-02-28  100

#include <iostream> using namespace std; typedef long long LL; const LL mod=1000000007; LL c,n; LL gcd(LL a,LL b) { return b==0?a:gcd(b,a%b);///欧几里得扩展算法求最大公约数 } LL power(LL p,LL n)//快速幂运算 { LL ans=1; while(n) { if(n&1) ans=ans*p%mod; p=p*p%mod; n/=2; } return ans; } LL exgcd(LL a,LL b,LL &x,LL &y)///扩展欧几里得算法,返回a,b的最大公约数,ax+by=gcd(a,b),x,y为方程的一组解 { if(b==0) { x=1; y=0; return a; } long long d=exgcd(b,a%b,x,y); long long t=x; x=y; y=t-a/b*y; return d; } int main() { int t;cin>>t; int cas=1; while(t--) { cin>>c>>n;///c---color n---lenth int ans=0; for(LL i=1;i<=n;i++)///循环节个数为gcd(n,i), 染色方案为 ∑c^gcd(n,i) 其中 i=1,2,3,4,....n { ans+=power(c,gcd(n,i));///旋转的情况 ans%=mod;///每一次计算取模一次 } ///以下为翻转的情况 if(n&1)///如果n为奇数 ans+=(n*power(c,n/2+1))%mod; else ans+=((n/2*power(c,n/2+1))%mod+(n/2*power(c,n/2))%mod)%mod; ///注意mod的位置 偶数有两种情况 ans%=mod; LL x,y; ///以下三行求2*n关于mod的逆元。 exgcd(2*n,mod,x,y);///此题为模1000000007 是一个素数,因此2*n和它的最大公约数为1,无需再进行判断。 ///注意:这里的置换群是2*n个 ///x=power(2*n,mod-2)%mod;//第二种方法 x=(x+mod)%mod;///防止出现负数的情况 cout<<"Case #"<<cas++<<": "<<ans*x%mod<<endl; } return 0; }参考网站: 点击打开链接
转载请注明原文地址: https://www.6miu.com/read-20036.html

最新回复(0)