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≤109,1≤L≤H≤109,H-L≤10^5

Solution

我用的是莫比乌斯反演加杜教筛

这题本来不需要莫反的,但最近都在练习莫反,那就用莫反做了

设\(F(d)\)代表在\([L,R]\)中选N个数,它们的gcd为d及其倍数的方案数

设\(f(d)\)代表在\([L,R]\)中选N个数,它们的gcd为d的方案数

\[F(n)=\sum_{n|d}f(d)=(\lfloor \frac{R}{n} \rfloor-\lfloor \frac{L-1}{n} \rfloor)^N
\]

上面式子的左边一半根据定义,右边一半的原因如下:

\(\lfloor \frac{R}{n} \rfloor\)其实是1到R中有多少个数整除n,\(\lfloor \frac{L-1}{n} \rfloor\)类似,那么它们相减之后,得到的就是\([L,R]\)中有多少个数可以整除n。根据题目的第一句话,我们知道选数是有序的,并且可以重复选。所以我们在得到了有多少个数整除n后,只要在里面有序地任选N个数,方案数是\((\lfloor \frac{R}{n} \rfloor-\lfloor \frac{L-1}{n} \rfloor)^N\),它们可以保证它们的gcd一定为n或n的倍数

接下来继续推

\[f(n)=\sum_{n|d}\mu(\frac{d}{n})F(d)=\sum_{n|d}\mu(\frac{d}{n})(\lfloor \frac{R}{d} \rfloor-\lfloor \frac{L-1}{d} \rfloor)^N
\]

改变枚举方式

\[f(n)=\sum_{d=1}^{\lfloor \frac{R}{n} \rfloor}\mu(d)(\lfloor \frac{R}{nd} \rfloor-\lfloor \frac{L-1}{nd} \rfloor)^N
\]

后面的东西整除分段加快速幂,前面的东西杜教筛

关于杜教筛,这里只给一个式子,有兴趣可以百度

\[S(n)=1-\sum_{i=2}^nS(\lfloor \frac{n}{i} \rfloor)\ \ \ \ (S(n)=\sum_{i=1}^n\mu(i))
\]

#include<bits/stdc++.h>
#define ll long long
const int Mod=1e9+7,MAXN=1e6+10,inf=0x3f3f3f3f;
int prime[MAXN],cnt,vis[MAXN],s[MAXN],mu[MAXN];
std::map<ll,ll> M;
template<typename T> inline void read(T &x)
{
T data=0,w=1;
char ch=0;
while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar();
if(ch=='-')w=-1,ch=getchar();
while(ch>='0'&&ch<='9')data=((T)data<<3)+((T)data<<1)+(ch^'0'),ch=getchar();
x=data*w;
}
template<typename T> inline void write(T x,char c='\0')
{
if(x<0)putchar('-'),x=-x;
if(x>9)write(x/10);
putchar(x%10+'0');
if(c!='\0')putchar(c);
}
template<typename T> inline void chkmin(T &x,T y){x=(y<x?y:x);}
template<typename T> inline void chkmax(T &x,T y){x=(y>x?y:x);}
template<typename T> inline T min(T x,T y){return x<y?x:y;}
template<typename T> inline T max(T x,T y){return x>y?x:y;}
inline void init()
{
memset(vis,1,sizeof(vis));
vis[0]=vis[1]=0;
mu[1]=1;
for(register int i=2;i<MAXN;++i)
{
if(vis[i])
{
prime[++cnt]=i;
mu[i]=-1;
}
for(register int j=1;j<=cnt&&i*prime[j]<MAXN;++j)
{
vis[i*prime[j]]=0;
if(i%prime[j])mu[i*prime[j]]=-mu[i];
else break;
}
}
for(register int i=1;i<MAXN;++i)s[i]=s[i-1]+mu[i];
}
inline ll qexp(ll a,ll b)
{
ll res=1;
while(b)
{
if(b&1)res=res*a%Mod;
a=a*a%Mod;
b>>=1;
}
return res;
}
inline ll MuSum(int x)
{
if(x<MAXN)return s[x];
if(M[x])return M[x];
ll res=1;
for(register int i=2;;)
{
if(i>x)break;
int j=x/(x/i);
res-=(ll)(j-i+1)*(ll)MuSum(x/i);
i=j+1;
}
return M[x]=res;
}
inline ll solve(int N,int L,int H)
{
ll res=0;
for(register int i=1;;)
{
if(i>H)break;
int j=min(H/(H/i),L/i?L/(L/i):inf);
(res+=qexp((ll)(H/i-L/i),N)*(ll)(MuSum(j)-MuSum(i-1))%Mod)%=Mod;
i=j+1;
}
return (res+Mod)%Mod;
}
int main()
{
init();
int N,K,L,H;
read(N);read(K);read(L);read(H);
write(solve(N,(L-1)/K,H/K),'\n');
return 0;
}

【刷题】BZOJ 3930 [CQOI2015]选数的更多相关文章

  1. BZOJ 3930: [CQOI2015]选数 递推

    3930: [CQOI2015]选数 Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeOnline/pro ...

  2. bzoj 3930: [CQOI2015]选数

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

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

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

  4. bzoj 3930: [CQOI2015]选数【递推】

    妙啊 这个题一上来就想的是莫比乌斯反演: \[ f(d)=\sum_{k=1}^{\left \lceil \frac{r}{d} \right \rceil}\mu(k)(\left \lceil ...

  5. 【递推】BZOJ 3930: [CQOI2015]选数

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

  6. bzoj 3930: [CQOI2015]选数【快速幂+容斥】

    参考:https://www.cnblogs.com/iwtwiioi/p/4986316.html 注意区间长度为1e5级别. 则假设n个数不全相同,那么他们的gcd小于最大数-最小数,证明:则gc ...

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

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

  8. 【BZOJ】3930: [CQOI2015]选数

    题意 从区间\([L, R]\)选\(N\)个数(可以重复),问这\(N\)个数的最大公约数是\(K\)的方案数.(\(1 \le N, K \le 10^9, 1 \le L \le R \le 1 ...

  9. 3930: [CQOI2015]选数

    Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 1958  Solved: 979[Submit][Status][Discuss] Descripti ...

随机推荐

  1. 我在华为,软件测试人员在工作中如何运用Linux?

    从事过软件测试的小伙们就会明白会使用Linux是多么重要的一件事,工作时需要用到,面试时会被问到,简历中需要写到.对于软件测试人员来说,不需要你多么熟练使用Linux所有命令,也不需要你对Linux系 ...

  2. gradle springboot 项目运行的三种方式

    一.java -jar 二.eclipse中 Java Application 三.命令行 gradle bootRun

  3. 关于matlab向文件写入数据的方法——留着备用

    MATLAB数据采集的时候,往往需要把得到的数据保存下来. fid = fopen(文件名,‘打开方式’): 说明:fid用于存储文件句柄值,如果fid>0,这说明文件打开成功.打开方式有如下选 ...

  4. 从零开始的Python学习Episode 20——面向对象(3)

    面向对象之封装 封装,即隐藏对象的属性和实现细节,仅对外公开接口,控制在程序中属性的读和修改的访问级别:将抽象得到的数据和行为(或功能)相结合,形成一个有机的整体. 隐藏 在python中用双下划线开 ...

  5. mysql 连接超时解决方案: 怎样修改默认超时时间

    mysql数据库有一个wait_timeout的配置,默认值为28800(即8小时). 在默认配置不改变的情况下,如果连续8小时内都没有访问数据库的操作,再次访问mysql数据库的时候,mysql数据 ...

  6. lscpi命令详解

    基础命令学习目录 lspci是一个用来查看系统中所有PCI总线以及连接到该总线上的设备的工具. 命令格式为 lspci -参数 (不加参数显示所有硬件设备) 至于有哪些参数及其详细用法可以看下这篇博客 ...

  7. chattr和lsattr命令详解

    基础命令学习目录首页 原文链接:http://www.ha97.com/5172.html PS:有时候你发现用root权限都不能修改某个文件,大部分原因是曾经用chattr命令锁定该文件了.chat ...

  8. Django之自带认证

    自带登录实例 {% extends "layout/base.html" %} // 所有link {% block body %} <div id="contai ...

  9. linux简单命令常用随记

    //查看网络信息 ifconfig //修改ip地址 ifconfig eth0 123.123.123.123 netmask 255.255.255.0 //网关设置 route add defa ...

  10. mybatis oracle和mysql like模糊查询写法

    oracle:RESOURCE_NAME LIKE '%' || #{resourceName} || '%'mysql:RESOURCE_NAME like concat(concat(" ...