BZOJ-3930 [CQOI2015]选数(莫比乌斯反演+杜教筛)
题目描述
从区间 \([L,R]\) 中选取 \(N\) 个整数,总共有 \((R-L+1)^{N}\) 种方案。对每种方案选出的 \(N\) 个整数都求一次最大公约数,求最大公约数刚好为 \(K\) 的选取方案有多少个。
数据范围:\(1\leq N,K\leq 10^{9},1\leq L\leq R\leq 10^{9},R-L\leq 10^{5}\)。
分析
题目即求:
\[\sum_{a_1=L}^{R}\sum_{a2=L}^{R}\cdots\sum_{a_n=L}^{R}[\gcd(a_1,a_2,\cdots,a_N)=K]
\]
根据套路,所有 \(a_i\) 都除 \(K\),则:
\[L\leq a_i\leq R\Longrightarrow L\leq a_i'\times K\leq R\Longrightarrow\Big\lceil\frac{L}{K}\Big\rceil\leq a_i'\leq \Big\lfloor\frac{R}{K}\Big\rfloor\Longrightarrow\ \Big\lfloor\frac{L+K-1}{K}\Big\rfloor \leq a_i'\leq \Big\lfloor\frac{R}{K}\Big\rfloor
\]
\[\begin{aligned}&\sum_{a_1=\lfloor \frac{L+K-1}{K}\rfloor}^{\lfloor\frac{R}{K}\rfloor}\sum_{a_2=\lfloor \frac{L+K-1}{K}\rfloor}^{\lfloor\frac{R}{K}\rfloor}\cdots\sum_{a_N=\lfloor \frac{L+K-1}{K}\rfloor}^{\lfloor\frac{r}{k}\rfloor}[\gcd(a_1,a_2,\cdots,a_N)=1]\\=&\sum_{a_1=L}^{R}\sum_{a2=L}^{R}\cdots\sum_{a_n=L}^{R}[\gcd(a_1,a_2,\cdots,a_N)=K]\\=&\sum_{a_1=\lfloor \frac{L+K-1}{K}\rfloor}^{\lfloor\frac{R}{K}\rfloor}\sum_{a_2=\lfloor \frac{L+K-1}{K}\rfloor}^{\lfloor\frac{R}{K}\rfloor}\cdots\sum_{a_N=\lfloor \frac{L+K-1}{K}\rfloor}^{\lfloor\frac{R}{K}\rfloor}\sum_{d\mid \gcd(a_1,a_2,\cdots,a_N)}\mu(d)\\=&\sum_{d=1}^{\lfloor\frac{R}{K}\rfloor}\mu(d)\sum_{a_1=\lfloor \frac{L+K-1}{K}\rfloor}^{\lfloor\frac{R}{K}\rfloor}\sum_{a_2=\lfloor \frac{L+K-1}{K}\rfloor}^{\lfloor\frac{R}{K}\rfloor}\cdots\sum_{a_N=\lfloor \frac{L+K-1}{K}\rfloor}^{\lfloor\frac{R}{K}\rfloor}[d\mid \gcd(a_1,a_1,\cdots,a_N)]\\=&\sum_{d=1}^{\lfloor\frac{R}{K}\rfloor}\mu(d)\sum_{a_1=\lfloor \frac{L+K-1}{K}\rfloor}^{\lfloor\frac{R}{K}\rfloor}[d\mid a_1]\sum_{a_2=\lfloor \frac{L+K-1}{K}\rfloor}^{\lfloor\frac{R}{K}\rfloor}[d\mid a_N]\cdots\sum_{a_N=\lfloor \frac{L+K-1}{K}\rfloor}^{\lfloor\frac{R}{K}\rfloor}[d\mid a_N]\\=&\sum_{d=1}^{\lfloor\frac{R}{K}\rfloor}\mu(d)\Big(\Big\lfloor\frac{R}{Kd}\Big\rfloor-\Big\lfloor\frac{L-1}{Kd}\Big\rfloor\Big)^N\end{aligned}
\]
对于 \(\mu\) 的前缀和,根据杜教筛公式:
\[S(n)=g(1)S(n)=\sum\limits_{i=1}^{n}(f\ast g)(i)-\sum\limits_{i=2}^{n}g(i)S\Big(\Big\lfloor\frac{n}{i}\Big\rfloor\Big)
\]
取 \(f=\mu,g=I,h=\mu\ast I=\epsilon\),则:
\[S(n)=1-\sum_{i=2}^{n}S\Big(\Big\lfloor\frac{n}{i}\Big\rfloor\Big)
\]
杜教筛 \(+\) 数论分块处理即可,时间复杂度 \(O(R^{\frac{2}{3}})\)。
代码
#include<bits/stdc++.h>
using namespace std;
const int N=2e6+10;//n^(2/3)
const int mod=1e9+7;
long long prime[N+10],vis[N+10],mu[N+10],sum[N+10],cnt;
long long quick_pow(long long a,long long b)
{
long long ans=1;
while(b)
{
if(b&1)
ans=ans*a%mod;
a=a*a%mod;
b>>=1;
}
return ans;
}
void init()
{
mu[1]=1;
for(int i=2;i<=N;i++)
{
if(!vis[i])
{
prime[++cnt]=i;
mu[i]=-1;
}
for(int j=1;j<=cnt&&i*prime[j]<=N;j++)
{
vis[i*prime[j]]=1;
if(i%prime[j]==0)
{
mu[i*prime[j]]=0;
break;
}
else
mu[i*prime[j]]=-mu[i];
}
}
for(int i=1;i<=N;i++)
sum[i]=(sum[i-1]+mu[i])%mod;
}
map<long long,long long> mp;
long long S_mu(long long n)
{
if(n<N)
return sum[n];
if(mp[n])
return mp[n];
long long ans=1;
for(long long l=2,r;l<=n;l=r+1)
{
r=n/(n/l);
ans=((ans-S_mu(n/l)*(r-l+1)%mod)%mod+mod)%mod;
}
mp[n]=(ans+mod)%mod;
return (ans+mod)%mod;
}
long long solve(long long N,long long K,long long L,long long R)
{
L=(L-1)/K;R=R/K;
long long ans=0;
for(long long l=1,r;l<=R;l=r+1)
{
if(L/l==0)
r=R/(R/l);
else
r=min(L/(L/l),R/(R/l));
ans=(ans+(S_mu(r)-S_mu(l-1))*quick_pow((R/l)-(L/l),N)%mod)%mod;
}
return (ans+mod)%mod;
}
int main()
{
init();
long long N,K,L,R;
cin>>N>>K>>L>>R;
cout<<solve(N,K,L,R)<<endl;
return 0;
}
posted on 2020-11-22 23:06 DestinHistoire 阅读(62) 评论(0) 收藏 举报