http://www.lydsy.com/JudgeOnline/problem.php?id=3930 (题目链接)
题意
求在${[L,R]}$中选出${n}$个数,可以相同,使得它们的${gcd=K}$的方案数。
Solution
首先,我们有一个性质:如果选出来的数不全相同,那么它们的${gcd}$不会超过选出来的最大数与最小数之差。
为什么是这样呢,更相减损术嘛。
所以就好做咯,枚举gcd,然后瞎搞搞,最后再把全部选一个数的方案加上就好了。
代码
// bzoj3930 #include<algorithm> #include<iostream> #include<cstdlib> #include<cstring> #include<cstdio> #include<cmath> #include<queue> #define LL long long #define inf 2147483640 #define MOD 1000000007 #define Pi acos(-1.0) #define free(a) freopen(a".in","r",stdin),freopen(a".out","w",stdout); using namespace std; const int maxn=100010; LL f[maxn]; int n,K,L,R; LL power(LL a,LL b) { LL res=1; while (b) { if (b&1) (res*=a)%=MOD; b>>=1;(a*=a)%=MOD; } return res; } int main() { scanf("%d%d%d%d",&n,&K,&L,&R); for (int i=R-L;i>=1;i--) if (i%K==0) { int l=(L-1)/i,r=R/i; f[i]=power(r-l,n)-(r-l); for (int j=2;i*j<=R-L;j++) f[i]=(f[i]-f[i*j]+MOD)%MOD; } if (K>=L && K<=R) (++f[K])%=MOD; printf("%lld",f[K]); return 0; }