BZOJ 3202 [Sdoi2013]项链
发布日期:2021-05-04 16:55:07 浏览次数:84 分类:技术文章

本文共 4505 字,大约阅读时间需要 15 分钟。

题目链接

题解

这题可以分成两部分:一个是统计珠子的个数,一个是统计项链的个数。

对于珠子的个数,记 S 3 S3 S3 gcd ⁡ = 1 \gcd=1 gcd=1的三个数的个数, S 2 S2 S2 gcd ⁡ = 1 \gcd=1 gcd=1的两个数的个数, S 1 S1 S1 gcd ⁡ = 1 \gcd=1 gcd=1的一个数的个数,容易发现答案就是

S 1 + 1 3 ( 3 S 2 − 3 S 1 ) + 1 6 ( S 3 − 3 S 2 + 2 S 1 ) = S 3 + 3 S 2 + 2 S 1 6 S1+\frac{1}{3}(3S2-3S1)+\frac{1}{6}(S3-3S2+2S1)=\frac{S3+3S2+2S1}{6} S1+31(3S23S1)+61(S33S2+2S1)=6S3+3S2+2S1
其中 S 1 = 1 S1=1 S1=1 S 2 , S 3 S2,S3 S2,S3可以用莫比乌斯反演求得
S 2 = ∑ T = 1 n ⌊ n T ⌋ 2 μ ( T ) , S 3 = ∑ T = 1 n ⌊ n T ⌋ 3 μ ( T ) S2=\sum_{T=1}^n \lfloor\frac{n}{T}\rfloor^2\mu(T),S3=\sum_{T=1}^n \lfloor\frac{n}{T}\rfloor^3\mu(T) S2=T=1nTn2μ(T),S3=T=1nTn3μ(T)
对于项链的个数,假设珠子的个数为 m m m,长度为 i i i的项链个数(不考虑旋转)为 f ( i ) f(i) f(i),由polya原理可得答案就是
1 n ∑ i = 1 n f ( gcd ⁡ ( i , n ) ) = 1 n ∑ d ∣ n f ( d ) φ ( n d ) \begin{aligned} & \frac{1}{n}\sum_{i=1}^n f(\gcd(i,n))\\ = & \frac{1}{n}\sum_{d|n}f(d)\varphi(\frac{n}{d}) \end{aligned} =n1i=1nf(gcd(i,n))n1dnf(d)φ(dn)
由于限制了相邻珠子不能相同,因此可以考虑 f ( i ) f(i) f(i)的递推式:要么从 f ( i − 1 ) f(i-1) f(i1)转移,此时当前珠子不能与两端相同;要么从 f ( i − 2 ) f(i-2) f(i2)转移,插入一个和第一个珠子相同的,再插入一个不同的,因此 f ( i ) f(i) f(i)的递推式为
f ( i ) = ( m − 2 ) f ( i − 1 ) + ( m − 1 ) f ( i − 2 ) f(i)=(m-2)f(i-1)+(m-1)f(i-2) f(i)=(m2)f(i1)+(m1)f(i2)
用特征方程解得
f ( i ) = ( − 1 ) i ( m − 1 ) + ( m − 1 ) i f(i)=(-1)^i(m-1)+(m-1)^i f(i)=(1)i(m1)+(m1)i
由于 n n n有可能是 1 0 9 + 7 10^9+7 109+7的倍数,此时没有逆元,因此可以先算模 ( 1 0 9 + 7 ) 2 (10^9+7)^2 (109+7)2的答案,如果 n n n 1 0 9 + 7 10^9+7 109+7的倍数直接除掉就可以了。

代码

#include 
#include
template
T read(){
T x=0; int f=1; char ch=getchar(); while((ch<'0')||(ch>'9')) {
if(ch=='-') {
f=-f; } ch=getchar(); } while((ch>='0')&&(ch<='9')) {
x=x*10+ch-'0'; ch=getchar(); } return x*f;}const int maxn=10000000;const int mo=1000000007;const long long mod=1ll*mo*mo;const long long inv6=833333345000000041ll;long long mul(long long x,long long y){
return (x*y-(long long)(((long double)x*y+0.5)/(long double)mod)*mod+mod)%mod;}int p[maxn+10],prime[maxn+10],cnt;long long mu[maxn+10];int getprime(){
p[1]=mu[1]=1; for(int i=2; i<=maxn; ++i) {
if(!p[i]) {
prime[++cnt]=i; mu[i]=mod-1; } for(int j=1; (j<=cnt)&&(i*prime[j]<=maxn); ++j) {
int x=i*prime[j]; p[x]=1; if(i%prime[j]==0) {
mu[x]=0; break; } mu[x]=mod-mu[i]; } } for(int i=2; i<=maxn; ++i) {
mu[i]+=mu[i-1]; if(mu[i]>=mod) {
mu[i]-=mod; } } return 0;}long long quickpow(long long a,long long b){
long long res=1; while(b) {
if(b&1) {
res=mul(res,a); } a=mul(a,a); b>>=1; } return res;}long long inv(long long x){
return quickpow(x,1ll*mo*(mo-1)-1);}long long bead(int a){
long long f=0,g=0; for(int l=1,r; l<=a; l=r+1) {
r=a/(a/l); f+=mul(mul(a/l,a/l),mu[r]-mu[l-1]+mod); if(f>=mod) {
f-=mod; } g+=mul(mul(a/l,a/l),mul(a/l,mu[r]-mu[l-1]+mod)); if(g>=mod) {
g-=mod; } } return mul(inv6,g+mul(3,f)+2);}long long phi(long long x){
long long res=x; if(res%mo==0) {
res=(res/mo)*(mo-1); x/=mo; } for(int i=2; 1ll*i*i<=x; ++i) {
if(x%i==0) {
res=mul(mul(res,i-1),inv(i)); } while(x%i==0) {
x/=i; } } if(x!=1) {
res=mul(mul(res,x-1),inv(x)); } return res;}long long F(long long n,long long m){
long long k=quickpow(m-1,n)+mul(quickpow((n&1)?(mod-1):1,n),m-1); if(k>=mod) {
k-=mod; } return k;}long long necklace(long long n,long long m){
long long ans=0; for(int i=1; 1ll*i*i<=n; ++i) {
if(n%i==0) {
ans+=mul(F(i,m),phi(n/i)); if(ans>=mod) {
ans-=mod; } if(1ll*i*i!=n) {
ans+=mul(F(n/i,m),phi(i)); if(ans>=mod) {
ans-=mod; } } } } return ans;}int T,m;long long n;int main(){
getprime(); T=read
(); while(T--) {
n=read
(); m=read
(); long long ans=necklace(n,bead(m)); printf("%lld\n",(ans%mo)?mul(ans,inv(n))%mo:mul((ans/mo),inv(n/mo))%mo); } return 0;}

转载地址:https://blog.csdn.net/wang3312362136/article/details/85676861 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:BZOJ 3309 DZY Loves Math
下一篇:BZOJ 2818 Gcd BZOJ 2820 YY的GCD

发表评论

最新留言

感谢大佬
[***.8.128.20]2024年04月29日 01时50分43秒