【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. ubunt tftp服务器搭建

    默认安装的Ubuntu系统没有包含TFTP的服务端和客户端,可以通过命令行来下载安装,步骤如下: (1)安装客户端. root@ www.linuxidc.com:~# apt-get install ...

  2. 反反爬虫 IP代理

    0x01 前言 一般而言,抓取稍微正规一点的网站,都会有反爬虫的制约.反爬虫主要有以下几种方式: 通过UA判断.这是最低级的判断,一般反爬虫不会用这个做唯一判断,因为反反爬虫非常容易,直接随机UA即可 ...

  3. 携程Apollo(阿波罗)配置中心在.NET Core项目快速集成

    .NET Core的支持文档大体上可以参考文档.Net客户端使用指南:https://github.com/ctripcorp/apollo/wiki/.Net%E5%AE%A2%E6%88%B7%E ...

  4. display 的 32 种写法

    从大的分类来讲, display的 32种写法可以分为 6个大类,再加上 1个全局类,一共是 7大类: 外部值 内部值 列表值 属性值 显示值 混合值 全局值 外部值 所谓外部值,就是说这些值只会直接 ...

  5. Java进阶之路——从初级程序员到架构师,从小工到专家

    原创文章 怎样学习才能从一名Java初级程序员成长为一名合格的架构师,或者说一名合格的架构师应该有怎样的技术知识体系,这是不仅一个刚刚踏入职场的初级程序员也是工作三五年之后开始迷茫的老程序员经常会问到 ...

  6. TCP/IP三次握手四次挥手

    本文通过图来梳理TCP-IP协议相关知识.TCP通信过程包括三个步骤:建立TCP连接通道,传输数据,断开TCP连接通道.如图所示,给出了TCP通信过程的示意图. TCP 三次握手四次挥手 主要包括三部 ...

  7. Centos安装jdk8

    1.下载jdk1.8的tar cd /usr/local/src #切换到该目录下 wget url #下载jdk8的tar包 2.下载完成后解压tar包 tar -zxvf jdk-8u152-li ...

  8. python介绍篇

    二进制编码ASSIC 每一个字符统一都需要8个bit来存储 计算机容量 1位 = 1bit 8bit = 1byte = 1字节 1024bytes = 1kbytes =1KB 1024个字符,小文 ...

  9. Linux PCI/PCI-E设备配置空间读取与修改

    Linux PCI/PCI-E设备配置空间读取与修改 1 前言 PCI和PCI Express,是计算机常使用的一种高速总线.操作系统中的PCI/PCI-E设备驱动以及操作系统内核,都需要访问PCI及 ...

  10. php替换文件指定行的内容

    //第一种 利用file 函数 读取文件,每一行都是一个数组元素 $arr = file($file); $arr[$line] = "hello"; file_put_conte ...