Description

我们知道,从区间[L,H](L和H为整数)中选取N个整数,总共有(H-L+1)^N种方案。小z很好奇这样选出的数的最大公约数的规律,他决定对每种方案选出的N个整数都求一次最大公约数,以便进一步研究。然而他很快发现工作量太大了,于是向你寻求帮助。你的任务很简单,小z会告诉你一个整数K,你需要回答他最大公约数刚好为K的选取方案有多少个。由于方案数较大,你只需要输出其除以1000000007的余数即可。

Input

输入一行,包含4个空格分开的正整数,依次为N,K,L和H。

Output

输出一个整数,为所求方案数。

Sample Input

2 2 2 4

Sample Output

3

HINT

样例解释

所有可能的选择方案:(2, 2), (2, 3), (2, 4), (3, 2), (3, 3), (3, 4), (4, 2), (4, 3), (4, 4)

其中最大公约数等于2的只有3组:(2, 2), (2, 4), (4, 2)

对于100%的数据,1≤N,K≤10^9,1≤L≤H≤10^9,H-L≤10^5

Sol

首先最重要的条件:(H-L)(10^5)以内,这说明区间内(gcd(i,j)<10^5),那么我们可以直接枚举gcd是多少,然后进行计算。

具体地,我们把H和L都/=K,这样所求变成了(gcd(a_1,a_2,...,a_n)=1)的方案数。

我们设(f[i])表示区间内(gcd)为i的方案数,那么(f[i])可以再次通过除以(i)然后直接求区间长度的方式解决,但是这样我们会把(sum_{i|d}f[d])也算上,所以需要把i倍数的d减掉,倒推即可。

本题的三个小细节:

  1. 如果K在L和R的范围内,那么ans++。
  2. 如果(L%K)不等于0,那么新的L等于(L/K+1),因为原来的L往后一小部分是不合法的,要去掉,内层统计时亦是如此。
  3. 要减去N个数都相同的方案,因为显然这种方案不成立,具体地,快速幂后面减个len就行。

时间复杂度(O(nlogn))

Code

#include <cstdio>
int N,K,L,R,l,r,M,m,F,f[100005],P=1e9+7;
int ksm(int a,int b){int res=1;for(;b;b>>=1,a=1ll*a*a%P) if(b&1) res=1ll*res*a%P;return res;}
int main()
{
    scanf("%d%d%d%d",&N,&K,&L,&R);
    if(L<=K&&K<=R) F++;
    L=L%K?L/K+1:L/K,R/=K,M=R-L+1;
    for(int i=M;i;i--)
    {
        l=L%i?L/i+1:L/i,r=R/i,m=r-l+1;
        if(l<r){f[i]=(ksm(m,N)-m+P)%P;for(int j=(i<<1);j<=M;j+=i) f[i]=(f[i]-f[j]+P)%P;}
    }
    printf("%dn",(F+f[1])%P);
}
内容来源于网络如有侵权请私信删除
你还没有登录,请先登录注册
  • 还没有人评论,欢迎说说您的想法!

相关课程

3603 0元 45元 限免
4099 9.8元 100元 0.98折