参考:https://www.cnblogs.com/iwtwiioi/p/4986316.html
注意区间长度为1e5级别。
则假设n个数不全相同,那么他们的gcd小于最大数-最小数,证明:则gcdk2−gcdk1=gcd(k2−k1)>d
所以特判一下全相等的情况就行利润
然后把区间除以k,这样问题就转成了找gcd==1,设f[i]为gcd为i的方案数。从大到小枚举约数,快速幂计算选取选取情况,然后减去约束的倍数的f(容斥)

#include<iostream>
#include<cstdio>
using namespace std;
const int N=100005,mod=1e9+7;
int n,k,l,r,len,p,f[N];
int ksm(int a,int b)
{
    int r=1;
    while(b)
    {
        if(b&1)
            r=1ll*r*a%mod;
        a=1ll*a*a%mod;
        b>>=1;
    }
    return r;
}
int main()
{
    scanf("%d%d%d%d",&n,&k,&l,&r);
    if(l<=k&&r>=k)
        p=1;
    l=(l-1)/k,r=r/k,len=r-l;
    for(int i=len;i>=1;i--)
    {
        int x=l/i,y=r/i;
        f[i]=(ksm(y-x,n)-y+x+mod)%mod;
        for(int j=i*2;j<=len;j+=i)
            f[i]=((f[i]-f[j])%mod+mod)%mod;
    }
    printf("%d\n",f[1]+p);
    return 0;
}

相关文章:

  • 2021-08-26
  • 2021-07-16
  • 2021-10-28
  • 2021-07-13
  • 2021-10-09
  • 2021-07-14
  • 2022-01-04
  • 2021-12-18
猜你喜欢
  • 2021-07-18
  • 2021-05-29
  • 2022-03-01
  • 2021-08-14
  • 2021-06-27
  • 2021-10-29
相关资源
相似解决方案