【BZOJ3930】选数(莫比乌斯反演,杜教筛)

题面

给定\(n,K,L,R\)

问从\(L~R\)中选出\(n\)个数,使得他们\(gcd=K\)的方案数

题解

这样想,既然\(gcd=K\),首先就把区间缩小一下

这样变成了\(gcd=1\)

设\(f(i)\)表示\(gcd\)恰好为\(i\)的方案数

那么,要求的是\(f(1)\)

设\(g(x)=\sum_{d|x}f(d)\)

所以\(g(x)\)表示\(x|gcd\)的方案数

这个不是很好求吗?

所以一波莫比乌斯反演

\[f(1)=\sum_{i=1}\mu(i)g(i)
\]

好的,看看\(g(x)\)怎么直接求

现在可以取的区间范围是\(L~R\)

要让\(gcd\)是\(x\)的倍数

区间的大小算一下,直接快速幂就行了

然后\(80\)分到手啦

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<set>
#include<map>
#include<vector>
#include<queue>
using namespace std;
#define MOD 1000000007
#define MAX 10000000
inline int read()
{
int x=0,t=1;char ch=getchar();
while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
if(ch=='-')t=-1,ch=getchar();
while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
return x*t;
}
int n,K,L,R;
bool zs[MAX];
int pri[MAX+1],tot,mu[MAX+1];
void pre()
{
zs[1]=true;mu[1]=1;
for(int i=2;i<=MAX;++i)
{
if(!zs[i])pri[++tot]=i,mu[i]=-1;
for(int j=1;j<=tot&&i*pri[j]<=MAX;++j)
{
zs[i*pri[j]]=true;
if(i%pri[j])mu[i*pri[j]]=-mu[i];
else break;
}
}
}
int fpow(int a,int b)
{
int s=1;
while(b){if(b&1)s=1ll*s*a%MOD;a=1ll*a*a%MOD;b>>=1;}
return s;
}
int G(int x,int L,int R)
{
L=(L-1)/x;R=R/x;
return fpow(R-L,n);
}
int main()
{
pre();
n=read();K=read();L=read();R=read();
int ans=0;
for(int i=K;i<=R;i+=K)
ans+=mu[i/K]*G(i,L,R)%MOD,ans%=MOD;
printf("%d\n",(ans+MOD)%MOD);
return 0;
}

现在的问题是\(L,R\)范围很大

但是我们又要求一个大的\(\mu\)

怎么办嗷。。

非线性时间诶。

杜教筛??

我们可以搞一下\(\mu\)的前缀和就行了,

这样两个相减就是\(\mu\)

设\(S(n)=\sum_{i=1}^n\mu(i)\)

\[g(1)S(n)=\sum_{i=1}^n(g*\mu)(i)-\sum_{i=2}^{n}g(i)S(\frac{n}{i})
\]

取\(g(x)=1\)

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

现在可以算出\(\mu\)啦

再回去看一下上面写的代码

发现可以数论分块

于是再来一次数论分块

这题就没啦

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<set>
#include<map>
#include<vector>
#include<queue>
using namespace std;
#define MOD 1000000007
#define MAX 10000000
inline int read()
{
int x=0,t=1;char ch=getchar();
while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
if(ch=='-')t=-1,ch=getchar();
while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
return x*t;
}
int n,K,L,R;
bool zs[MAX];
int pri[MAX+1],tot,mu[MAX+1],smu[MAX+1];
map<int,int> M;
void pre()
{
zs[1]=true;mu[1]=1;
for(int i=2;i<=MAX;++i)
{
if(!zs[i])pri[++tot]=i,mu[i]=-1;
for(int j=1;j<=tot&&i*pri[j]<=MAX;++j)
{
zs[i*pri[j]]=true;
if(i%pri[j])mu[i*pri[j]]=-mu[i];
else break;
}
}
for(int i=1;i<=MAX;++i)smu[i]=smu[i-1]+mu[i];
}
int fpow(int a,int b)
{
int s=1;
while(b){if(b&1)s=1ll*s*a%MOD;a=1ll*a*a%MOD;b>>=1;}
return s;
}
int SMu(int x)
{
if(x<=MAX)return smu[x];
if(M[x])return M[x];
int ret=1;
for(int i=2,j;i<=x;i=j+1)
{
j=x/(x/i);
ret-=(j-i+1)*SMu(x/i);
}
return M[x]=ret;
}
int main()
{
pre();
n=read();K=read();L=read();R=read();
L=(L-1)/K;R/=K;
int ans=0;
for(int i=1,j;i<=R;i=j+1)
{
j=R/(R/i);if(i<=L)j=min(j,L/(L/i));
ans+=(SMu(j)-SMu(i-1))*fpow(R/i-L/i,n)%MOD;
ans%=MOD;
}
printf("%d\n",(ans+MOD)%MOD);
return 0;
}

【BZOJ3930】选数(莫比乌斯反演,杜教筛)的更多相关文章

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

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

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

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

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

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

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

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

  5. [复习]莫比乌斯反演,杜教筛,min_25筛

    [复习]莫比乌斯反演,杜教筛,min_25筛 莫比乌斯反演 做题的时候的常用形式: \[\begin{aligned}g(n)&=\sum_{n|d}f(d)\\f(n)&=\sum_ ...

  6. P4450-双亲数,P5221-Product,P6055-[RC-02]GCD【莫比乌斯反演,杜教筛】

    除了最后一题都比较简单就写一起了 P4450-双亲数 题目链接:https://www.luogu.com.cn/problem/P4450 题目大意 给出\(A,B,d\)求有多少对\((a,b)\ ...

  7. 51nod 1237 最大公约数之和 V3【欧拉函数||莫比乌斯反演+杜教筛】

    用mu写lcm那道卡常卡成狗(然而最后也没卡过去,于是写一下gcd冷静一下 首先推一下式子 \[ \sum_{i=1}^{n}\sum_{j=1}^{n}gcd(i,j) \] \[ \sum_{i= ...

  8. 【bzoj4176】Lucas的数论 莫比乌斯反演+杜教筛

    Description 去年的Lucas非常喜欢数论题,但是一年以后的Lucas却不那么喜欢了. 在整理以前的试题时,发现了这样一道题目"求Sigma(f(i)),其中1<=i< ...

  9. 【CCPC-Wannafly Winter Camp Day3 (Div1) F】小清新数论(莫比乌斯反演+杜教筛)

    点此看题面 大致题意: 让你求出\(\sum_{i=1}^n\sum_{j=1}^n\mu(gcd(i,j))\). 莫比乌斯反演 这种题目,一看就是莫比乌斯反演啊!(连莫比乌斯函数都有) 关于莫比乌 ...

  10. LOJ#6229. 这是一道简单的数学题(莫比乌斯反演+杜教筛)

    题目链接 \(Description\) 求\[\sum_{i=1}^n\sum_{j=1}^i\frac{lcm(i,j)}{gcd(i,j)}\] 答案对\(10^9+7\)取模. \(n< ...

随机推荐

  1. arm 异常处理结构

    概念:正常的程序执行过程中发生暂时的停止称为异常,如果发现异常情况,将会进行异常处理 作用:快速响应用户的行为,提高cpu的响应能力 异常类型: 异常处理的三个步骤: 1.保护现场: 工作模式保存:C ...

  2. 【Oracle】虚拟表Dual

    Dual是个虚拟表,用来构成SELECT语句的语法规则,Oracle保证Dual里面永远只有一条记录.可以用它来做很多事情,例如,查看当前用户:用来调用系统函数:得到序列的下一个值或者当前值:可以用作 ...

  3. Linux下的压力测试工具:ab、http_load、webbench、siege

    一.ab 1.1 介绍 ab是apache自带的一款功能强大的测试工具.      安装了apache一般就自带了. 1.2 下载 同apache. 1.3 安装 同apache. 1.4 安装结果 ...

  4. docker swarm集群搭建

    本文来自我的github pages博客http://galengao.github.io/ 即www.gaohuirong.cn 摘要: swarm是docker原生的集群管理软件,与kuberne ...

  5. springmvc log4j 配置

    web.xml 增加 <context-param> <param-name>log4jConfigLocation</param-name> <param- ...

  6. .NET常用第三方库(包)总结

    文章会不定期更新,以下内容均为个人总结,欢迎各位拍砖指正 序列化与反序列化 JSON.NET应该是.NET平台上使用最为广泛的序列化/反序列化包了,ASP.NET和ASP.NET Core中默认序列化 ...

  7. Python自动化--语言基础8--接口请求及封装

    基于http协议,最常用的是GET和POST两种方法. 接口文档需要包含哪些信息: 接口名称接口功能接口地址支持格式 json/xml请求方式请求示例请求参数(是否必填.数据类型.传递参数格式)返回参 ...

  8. CEF小白人系列2-DEV环境配置-Windows10+SDK+VS2015

    以下资料整理来自CEF官方教学.作者做了翻译和整理.并会以一种重事件操作的方式来一点点入门. 3个问题: 在上一篇内容中我们了解了什么是CEF,能干些什么.必要的物理学习环境. 下面我们也是以带着问题 ...

  9. DB2物化视图——MQT 物化查询表的正确使用(materialized query tables)

    我们今天主要向大家讲述的是DB2物化视图——MQT 物化查询表使用,以下就是对DB2物化视图之MQT物化查询表的正确使用的主要内容的详细描述,望大家在浏览之后会对其有更深的了解. MQT 的定义基于查 ...

  10. 麻省理工18年春软件构造课程阅读02“Java基础”

    本文内容来自MIT_6.031_sp18: Software Construction课程的Readings部分,采用CC BY-SA 4.0协议. 由于我们学校(哈工大)大二软件构造课程的大部分素材 ...