Description
给定n,a,b,求这个东西
{
∑
m
=
0
n
[
(
n
m
)
%
2
]
}
∑
i
=
1
n
∑
j
=
1
i
−
1
gcd
(
a
i
−
b
i
,
a
j
−
b
j
)
\left\{\sum_{m=0}^n\left[{\binom{n}{m}} \%2\right]\right\}\sum_{i=1}^n\sum_{j=1}^{i-1}\gcd\left(a^i-b^i,a^j-b^j\right)
{m=0∑n[(mn)%2]}i=1∑nj=1∑i−1gcd(ai−bi,aj−bj)
n
≤
1
0
5
,
gcd
(
a
,
b
)
=
1
n\le10^5,\gcd(a,b)=1
n≤105,gcd(a,b)=1
Solution
小米竟然还有oj,我火星了
先看后面那一坨
说一个结论,就是当
gcd
(
a
,
b
)
=
1
\gcd(a,b)=1
gcd(a,b)=1时,
gcd
(
a
n
−
b
n
,
a
m
−
b
m
)
=
a
gcd
(
n
,
m
)
−
b
gcd
(
n
,
m
)
\gcd\left(a^n-b^n,a^m-b^m\right)=a^{\gcd\left(n,m\right)}-b^{\gcd\left(n,m\right)}
gcd(an−bn,am−bm)=agcd(n,m)−bgcd(n,m)
这个的证明可以考虑设
d
=
gcd
(
n
,
m
)
d=\gcd\left(n,m\right)
d=gcd(n,m),然后提取一个(a-b)暴力逆展开,这里就不写了(滑稽
于是就看起来可做了,化成下面这个样子
1
2
[
∑
d
=
1
n
(
a
d
−
b
d
)
∑
x
=
1
⌊
n
d
⌋
μ
(
x
)
(
⌊
n
d
x
⌋
)
2
]
−
∑
i
=
1
n
(
a
i
−
b
i
)
\frac{1}{2}\left[\sum_{d=1}^n\left(a^d-b^d\right)\sum_{x=1}^{\lfloor\frac{n}{d}\rfloor}\mu(x){\left(\lfloor\frac{n}{dx}\rfloor\right)}^2\right]-\sum_{i=1}^{n}\left(a^i-b^i\right)
21⎣⎡d=1∑n(ad−bd)x=1∑⌊dn⌋μ(x)(⌊dxn⌋)2⎦⎤−i=1∑n(ai−bi)
实际上还可以继续化变成O(n)预处理根号求的做法,但是我们这样就已经可以跑过了
然后看看前面那一坨,我们发现实际上就是统计组合数某一行的奇偶性
再说一个结论,就是
(
n
m
)
≡
[
m
&
n
=
n
]
(
m
o
d
2
)
\binom{n}{m}\equiv[m\&n=n]\pmod2
(mn)≡[m&n=n](mod2)
这个的证明可以考虑归纳一下,然后大力讨论四种情况即可
于是就做完了。。
Code
#include <stdio.h>
#include <string.h>
#include <algorithm>
#define rep(i,st,ed) for (int i=st;i<=ed;++i)
typedef long long LL;
const int MOD=1e9+7;
const int ny2=(MOD+1)/2;
const int N=200005;
LL ta[N],tb[N],mu[N];
int p[N];
bool np[N];
void upd(LL &x,LL v) {
x+=v; (x>=MOD)?(x-=MOD):0;
}
void pre(int n) {
mu[1]=1;
rep(i,2,n) {
if (!np[i]) p[++p[0]]=i,mu[i]=MOD-1;
for (int j=1;i*p[j]<=n&&j<=p[0];++j) {
np[i*p[j]]=1;
if (i%p[j]==0) {mu[i*p[j]]=0; break;}
mu[i*p[j]]=MOD-mu[i];
}
}
}
LL ksm(LL x,LL dep) {
LL res=1;
for (;dep;dep>>=1) {
(dep&1)?(res=res*x%MOD):0;
x=x*x%MOD;
}
return res;
}
int main(void) {
int n,a,b; scanf("%d%d%d",&n,&a,&b);
pre(n); LL ans=0,wjp=0; ta[0]=tb[0]=1;
rep(i,1,n) ta[i]=ta[i-1]*a%MOD,tb[i]=tb[i-1]*b%MOD;
rep(i,0,n) if ((i&n)==i) upd(wjp,1);
rep(d,1,n) {
LL tmp=0;
rep(x,1,(n/d)) {
upd(tmp,mu[x]*(n/(d*x))%MOD*(n/(d*x))%MOD);
}
tmp=tmp*(ta[d]-tb[d]+MOD)%MOD;
upd(ans,tmp);
}
rep(i,1,n) upd(ans,tb[i]),upd(ans,MOD-ta[i]);
ans=ans*ny2%MOD;
printf("%lld\n", wjp*ans%MOD);
return 0;
}