手动博客搬家:本文发表于20180310 11:46:11, 原地址https://blog.csdn.net/suncongbo/article/details/79506484

题目链接:

(Luogu)https://www.luogu.org/problemnew/show/P3172

(BZOJ)http://www.lydsy.com/JudgeOnline/problem.php?id=3930

题目大意:

给定N,M,L,R,从区间[L,R]内选出N个整数使得它们的gcd恰好为m,求合法的选数方案数对1e9+7取模的值。1<=N,M,L,R<=1e9, R-L<=1e5.

思路分析:

gcd? 那就莫比乌斯反演好了。

令F(m)表示从[L,R]中选出N个数,其gcd为m的倍数的方案数。

f(m)表示从[L,R]中选出N个数,其gcd 恰好为m方案数。(莫比乌斯反演常见做法)

我们要求的是f(m),为了简化运算,我们令l等于大于等于L的最小的m的倍数,r等于小于等于L的最大的m的倍数。然后l/=m,r/=m,问题转化为求f(1). (莫比乌斯反演常见做法)

根据莫比乌斯反演公式$$F(n)=\sum_{n|d} f(d), f(n)=\sum_{n|d}\mu (\frac{d}{n})F(d)$$, F(n)可以O(1)求得,直接反演即可。

现在面临两个问题:

  1. F(x)和f(x)的定义域是什么?
  2. 如何O(1)求F(x)?

先来解决第二个问题:

F(x)其实就是[l,r]内是x的倍数的数的个数的N次方,可以用快速幂求得。具体见代码getF函数。

难点在于第一个问题:

首先我们知道,定义域不超过r. 而r=R/M是1e9级别的,因此必须优化,发现更多的性质。

F(x)既然表示选出N个数gcd为x的方案数,那我们观察以下式子$$\gcd (x,y)\le y-x (x<y)$$如果选的数不全相等,那它们的gcd一定不会超过r-l, 也就是F(x)和f(x)的定义域就会缩小到r-l, 而r-l是1e5级别的!这就很美妙了!

现在只要处理一下选出的所有数全相等的情况了。

为了缩小定义域,我们给F(x)和f(x)分别添加一个条件: F(x)表示表示从[L,R]中选出不全相等的 N个数,其gcd为x的倍数的方案数,f(x)表示表示从[L,R]中选出不全相等的 N个数,其gcd 恰好为x的方案数,枚举定义域[1,r-l]莫比乌斯反演求出f(1)即可。

而定义变了以后,O(1)计算F(x)的方法也出现了变动: $$F(x)=a^N-a$$其中a为[l,r]内是x的倍数的数的个数。公式解释: 如果是随意选,共有\(a^N\)种选法,然后去掉全部相等的选法,选N个全部相等的数就相当于只选一个数,因此有a种选法,从\(a^N\)中扣除。

以上是计算f(1)的方法。

f(1)算完后,还要加上从[l,r]中选N个全相等的数使得gcd为1的方案数。那显然唯一方案就是全选1,如果1被包含在区间[l,r]中答案就是f(1)+1,否则答案为f(1).

代码实现:

#include<cstdio>
using namespace std; const int N = 1e5+1;
const long long P = 1e9+7;
long long n,m,lb,rb;
int mu[N+4];
long long p[N+4];
bool f[N+4];
int pn; void Mobius()
{
mu[1] = 1; pn = 0;
for(int i=2; i<=N; i++)
{
if(!f[i]) {pn++; p[pn] = i; mu[i] = -1;}
for(int j=1; j<=pn && i*p[j]<=N; j++)
{
f[p[j]*i] = true;
if(i%p[j]==0) {mu[i*p[j]] = 0; break;}
else mu[i*p[j]] = -mu[i];
}
}
} long long quickpow(long long a,long long b)
{
a %= P;
long long cur = a,ret = 1ll;
for(int i=0; b; i++)
{
if(b&(1ll<<i)) {ret *= cur; ret %= P; b-=(1ll<<i);}
cur *= cur; cur %= P;
}
return ret;
} long long getF(long long a)
{
long long lt,rt;
if(lb%a>0ll) lt = lb/a+1;
else lt = lb/a;
rt = rb/a;
return (quickpow(rt-lt+1,n)-(rt-lt+1)+P)%P;
} int main()
{
Mobius();
scanf("%lld%lld%lld%lld",&n,&m,&lb,&rb);
if(lb%m>0ll) lb = lb/m+1;
else lb = lb/m;
rb/=m;
long long nn = rb-lb,ans = 0ll;
for(int i=1; i<=nn; i++)
{
ans += mu[i]*getF(i);
ans = (ans+P)%P;
}
if(lb<=1 && 1<=rb) {ans++; ans%=P;}
printf("%lld\n",ans);
return 0;
}

BZOJ 3930 Luogu P3172 选数 (莫比乌斯反演)的更多相关文章

  1. [BZOJ 3930] [CQOI 2015]选数(莫比乌斯反演+杜教筛)

    [BZOJ 3930] [CQOI 2015]选数(莫比乌斯反演+杜教筛) 题面 我们知道,从区间\([L,R]\)(L和R为整数)中选取N个整数,总共有\((R-L+1)^N\)种方案.求最大公约数 ...

  2. BZOJ 3930: [CQOI2015]选数 莫比乌斯反演

    https://www.lydsy.com/JudgeOnline/problem.php?id=3930 https://blog.csdn.net/ws_yzy/article/details/5 ...

  3. 【bzoj3930】[CQOI2015]选数 莫比乌斯反演+杜教筛

    题目描述 我们知道,从区间[L,H](L和H为整数)中选取N个整数,总共有(H-L+1)^N种方案.小z很好奇这样选出的数的最大公约数的规律,他决定对每种方案选出的N个整数都求一次最大公约数,以便进一 ...

  4. 【BZOJ3930】[CQOI2015]选数 莫比乌斯反演

    [BZOJ3930][CQOI2015]选数 Description 我们知道,从区间[L,H](L和H为整数)中选取N个整数,总共有(H-L+1)^N种方案.小z很好奇这样选出的数的最大公约数的规律 ...

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

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

  6. luogu3172 [CQOI2015]选数 莫比乌斯反演+杜教筛

    link 题目大意:有N个数,每个数都在区间[L,H]之间,请求出所有数的gcd恰好为K的方案数 推式子 首先可以把[L,H]之间的数字gcd恰好为K转化为[(L-1)/K+1,H/K]之间数字gcd ...

  7. [BZOJ 2154]Crash的数字表格(莫比乌斯反演+数论分块)

    [BZOJ 2154]Crash的数字表格(莫比乌斯反演+数论分块) 题面 求 \[\sum_{i=1}^{n} \sum_{j=1}^{m} \mathrm{lcm}(i,j)\] 分析 \[\su ...

  8. [BZOJ 2301] [HAOI 2011] Problem b (莫比乌斯反演)(有证明)

    [BZOJ 2301] [HAOI 2011] Problem b (莫比乌斯反演)(有证明) 题面 T组询问,每次给出a,b,c,d,k,求\(\sum _{i=a}^b\sum _{j=c}^d[ ...

  9. luogu 4844 LJJ爱数数 (莫比乌斯反演+数学推导)

    题目大意:求满足gcd(a,b,c)==1,1/a+1/b=1/c,a,b,c<=n的{a,b,c}有序三元组个数 因为题目里有LJJ我才做的这道题 出题人官方题解https://www.cnb ...

随机推荐

  1. [Java]LeetCode57 Insert Interval

    Given a set of non-overlapping intervals, insert a new interval into the intervals (merge if necessa ...

  2. Android 系统开机logo的修改【转】

    本文转载自:http://blog.csdn.net/yandongqiangZHRJ/article/details/8585273 看到了好几个修改logo的博文,但是说的不是很清楚,在这里亲手送 ...

  3. 【撸码caffe四】 solver.cpp&&sgd_solver.cpp

    caffe中solver的作用就是交替低啊用前向(forward)算法和后向(backward)算法来更新参数,从而最小化loss,实际上就是一种迭代的优化算法. solver.cpp中的Solver ...

  4. 基于Spark的网站日志分析

    本文只展示核心代码,完整代码见文末链接. Web Log Analysis 提取需要的log信息,包括time, traffic, ip, web address 进一步解析第一步获得的log信息,如 ...

  5. Android网络连接监听

    接收系统网络服务的广播接收者 public class NetStateReceiver extends BroadcastReceiver { private Handler handler; pu ...

  6. Docker容器的使用和连接

    在上一篇文章<Docker从安装部署到Hello World>介绍了如何在CentOS7上安装Docker.这篇文章主要介绍一下Docker容器的使用和连接. vDocker 容器使用 1 ...

  7. go的常量与变量

    一.常量 1.1 定义 常量使用关键字const 定义,用于存储不会变化的数据 定义方法 const identifier [type] = value package main // 常量定义 co ...

  8. Beta冲刺-星期五

    这个作业属于哪个课程  <课程的链接>            这个作业要求在哪里 <作业要求的链接> 团队名称 Three cobblers 这个作业的目标 完成项目最后的冲刺 ...

  9. CNN结构:MXNet设计和实现简介

    对原文有大量修改,如有疑惑,请移步原文. 参考链接:MXNet设计和实现简介 文章翻译于:https://mxnet.incubator.apache.org/architecture/index.h ...

  10. OpenCV: 图像连通域检测的递归算法

    序言:清除链接边缘,可以使用数组进行递归运算; 连通域检测的递归算法是定义级别的检测算法,且是无优化和无语义失误的. 同样可用于寻找连通域 void ClearEdge(CvMat* MM,CvPoi ...