BZOJ 3930: [CQOI2015]选数 莫比乌斯反演 + 杜教筛

$\Rightarrow \sum_{i=\frac{L}{k}}^{\frac{R}{k}}\sum_{i'=\frac{L}{k}}^{\frac{R}{k}}....[gcd_{i=1}^{n}(i)==1]$

$\Rightarrow \sum_{i=\frac{L}{k}}^{\frac{R}{k}}\sum_{i'=\frac{L}{k}}^{\frac{R}{k}}....\sum_{d|gcd_{i=1}^{n}(i)}\mu(d)$

$\Rightarrow\sum_{d=1}^{\frac{R}{d}}\mu(d)(\left \lfloor \frac{R}{kd} \right \rfloor-\left \lfloor \frac{L-1}{kd} \right \rfloor)^n$

#include<bits/stdc++.h>
#define maxn 1040000
#define M 1000001
#define inf 0x7f7f7f7f
#define ll long long
using namespace std;
ll mod = 1000000007;
void setIO(string s)
{
string in=s+".in";
freopen(in.c_str(),"r",stdin);
}
map<int,ll>ansmu;
int cnt;
bool vis[maxn];
int prime[maxn], mu[maxn];
ll sumv[maxn];
ll qpow(ll base,ll k)
{
ll tmp=1;
while(k)
{
if(k&1) tmp=tmp*base%mod;
base=base*base%mod;
k>>=1;
}
return tmp;
}
void Linear_shaker()
{
mu[1]=1;
int i,j;
for(i=2;i<=M;++i)
{
if(!vis[i]) prime[++cnt]=i, mu[i]=-1;
for(j=1;j<=cnt&&1ll*i*prime[j]<=M;++j)
{
vis[i*prime[j]]=1;
if(i%prime[j]==0)
{
mu[i*prime[j]]=0;
break;
}
mu[i*prime[j]]=-mu[i];
}
}
for(i=1;i<=M;++i) sumv[i]=(sumv[i-1]+mu[i]+mod)%mod;
}
ll get(ll n)
{
if(n<=M) return sumv[n];
if(ansmu[n]) return ansmu[n];
ll i,j,re=0;
for(i=2;i<=n;i=j+1)
{
j=(n/(n/i));
re=(re+(j-i+1)%mod*get(n/i)%mod+mod)%mod;
}
return ansmu[n]=(1ll-re+mod)%mod;
}
int main()
{
// setIO("input");
ll n,k,L,R,i,j,re=0;
scanf("%lld%lld%lld%lld",&n,&k,&L,&R);
L = (L - 1) / k, R = R / k;
Linear_shaker();
for(i=1;i<=R;i=j+1)
{
j=min(R/(R/i), L/i?L/(L/i):inf);
re=(re+qpow(R/i-L/i, n) * (get(j)-get(i-1)+mod)%mod)%mod;
}
printf("%lld\n",re);
return 0;
}


posted @ 2019-06-27 14:33  EM-LGH  阅读(125)  评论(0编辑  收藏  举报