[CQOI2015]选数
若L%k==0,那么累加的下界为 ,若L%k!=0,那么累加的下界为 ,综合一下,下界为 。
我们设下界 = t 。
把a除掉后,上届为 ,下界为 = 。
因此,可以对 g(d) 进行数论分块,通过杜教筛求莫比乌斯函数的前缀和。
code:
#include
using namespace std;
typedef long long ll;
const int MAX = 1e6;
const ll MOD = 1000000007;
ll n,k,L,H;
ll mu[MAX+10],prime[MAX+10];
bool check[MAX+10];
inline ll read()
{
register ll x=0,t=1;register char ch=getchar();
while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
if(ch=='-')t=-1,ch=getchar();
while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
return x*t;
}
void get_sum()
{
memset(check,false,sizeof(check));
mu[1]=1;
int tot=0;
for(int i=2;i<=MAX;i++){
if(!check[i]){
prime[tot++]=i;
mu[i]=-1;
}
for(int j=0;jdp;
ll cal(ll x)
{
if(x<=MAX) return mu[x];
if(dp[x]) return dp[x];
ll pos;
ll tmp=0;
for(ll i=2;i<=x;i=pos+1){
pos=x/(x/i);
tmp+=(pos-i+1)*cal(x/i);
}
dp[x]=1-tmp;
return dp[x];
}
ll multiply(ll a, ll b)
{
ll ans = 1;
while (b)
{
if (b & 1)
{
ans = ((ans%MOD)*(a%MOD)) % MOD;
b--;
}
b /= 2;
a = ((a%MOD)*(a%MOD)) % MOD;
}
return ans;
}
int main()
{
get_sum();
n=read();
k=read();
L=read();
H=read();
ll ans=0;
ll x=H/k;
ll y=(L-1)/k;
ll pos=0;
ll i;
for(i=1;i<=x;i=pos+1){
if(i<=y)
pos=min(x/(x/i),y/(y/i));
else
pos=x/(x/i);
ans=(ans+multiply(x/i-y/i,n)*((cal(pos)-cal(i-1)+MOD)%MOD)%MOD)%MOD;
}
printf("%lld\n",ans);
return 0;
}