前言:

很久以前看过了线性筛,没怎么注意原理,但是后来发现线性筛还有很有用的。。

比如上次做的一道题就需要找出每个数的最小质因子,先筛再找就太慢了。。一看线性筛发现就可以直接在筛的过程中处理出来了!

今天又学习了屌炸天的jzp线性筛,可以在o(n)的时间内求出欧拉函数, 莫比乌斯函数等积性函数

原理:

首先jzp线性筛并不是一种新的线性筛。。其实就是jzp大牛对线性筛的一些开发应用

先回忆一下积性函数的定义 若a,b互质 则f(ab)=f(a)*f(b)的函数f 定义为积性函数,不要求a,b互质也满足的称为完全积性函数

欧拉函数和莫比乌斯函数都是积性函数但不是完全积性函数

假如我们要求 欧拉函数f(n)和莫比乌斯函数 mb(n)

显然如果n的所有质因数(p1,p2...)的次数都是1,显然p1,p2....是互质的,满足积性函数定义,则f(n)=f(p1)*f(p2).....同理mb(n)

而如果某个质因数p的次数不为1,假设为k,我们可以看(yy)出 f(p^k)=p^k-p^(k-1)=(p-1)*p^k,同时由mobius函数定义知如果某个质因数次数大于1次,则其函数值为0

那么如何在线性筛中找到次数不为1的质因子呢

我们观察 if(i%prime[j]==0) break; 这句代码,此处要筛的数n =i*prime[j],而当i%prime[j]==0 时 显然n%(prime[j]*prime[j])==0。

因此可以知道此时在n的质因子中 prime[j]的次数已经大于1了,就可以处理相应的欧拉函数和莫比乌斯函数了!

简单应用:

hdu1695

题意:
求[1,n]和[1,m]之间有多少个互质的数

做法:
以前是用容斥做的,但是容斥需要找质因数,再二进制枚举,比较慢

莫比乌斯函数其实就是容斥的系数,所以直接枚举可能出现的约数(其实就是1~n)用莫比乌斯函数求和即可

最后的式子(不判重)为sum(i=1 to n , mb(i)*(n/i)*(m/i));

这里还有一个小优化,由于是整数除法,对于i=[a,n/(n/a)]   n/i都是是一样的 ,比如 100/(21,22...25)都等于4,这样可以提前对莫比乌斯函数求前缀和,直接累加即可

具体实现见代码,大神们证明了这个优化可以把复杂度降到sqrt(n)级别。具体实现起来的确是快多了,hdu直接0ms AC了!

代码:

#include <iostream>
#include <stdio.h>
#include<string.h>
#include<algorithm>
#include<string>
#include<ctype.h>
using namespace std;
#define maxn 100000
bool notprime[maxn+];
int prime[maxn+];
int mb[maxn+];
int f[maxn+];
long long sum[maxn+];
int np;
long long n,m;
void jzp()
{
np=;
memset(notprime,,sizeof(notprime));
mb[]=;
for(int i=; i<=maxn; i++)
{
if(!notprime[i])
{
prime[np++]=i;
mb[i]=-;
//f[i]=i-1;
}
for(int j=; j<np&&i*prime[j]<=maxn; j++)
{
notprime[i*prime[j]]=;
if(i%prime[j]==)
{
mb[i*prime[j]]=;
//f[i*prime[j]]=f[i]*prime[j];
break;
}
else
{
mb[i*prime[j]]=-mb[i];
//f[i*prime[j]]=f[i]*(prime[j]-1);
}
}
}
}
int main()
{
int t,cas=;
scanf("%d",&t);
jzp();
sum[]=;
for(int i=;i<=maxn;i++)
{
sum[i]=sum[i-]+mb[i];
}
while(t--)
{
int a,b,c,d,k;
scanf("%d%d%d%d%d",&a,&b,&c,&d,&k);
if(k==)
{
printf("Case %d: 0\n",cas++);
continue;
}
n=min(b/k,d/k);
m=max(b/k,d/k);
long long ans=;
for(int i=;i<=n;i++)
{
int j=n/(n/i);
ans+=(n/i)*(n/i)*(sum[j]-sum[i-]);
i=j;
}
ans=-(ans/);
for(int i=;i<=n;i++)
{
int j=min(m/(m/i),n/(n/i));
ans+=(n/i)*(m/i)*(sum[j]-sum[i-]);
i=j;
}
printf("Case %d: %I64d\n",cas++,ans);
}
return ;
}

最后贴jzp筛模板

bool notprime[maxn+];
int prime[maxn+];
int mb[maxn+]; //mobius
int f[maxn+]; //euler
int np;
void jzp()
{
np=;
memset(notprime,,sizeof(notprime));
mb[]=;
for(int i=;i<=maxn;i++)
{
if(!notprime[i])
{
prime[np++]=i;
mb[i]=-;
f[i]=i-;
}
for(int j=;j<np&&i*prime[j]<=maxn;j++)
{
notprime[i*prime[j]]=;
if(i%prime[j]==)
{
mb[i*prime[j]]=;
f[i*prime[j]]=f[i]*prime[j];
break;
}
else
{
mb[i*prime[j]]=-mb[i];
f[i*prime[j]]=f[i]*(prime[j]-);
}
}
}
}

jzp线性筛及其简单应用的更多相关文章

  1. 【数论线性筛】洛谷P1865 A%B problem

    题目背景 题目名称是吸引你点进来的 实际上该题还是很水的 题目描述 区间质数个数 输入输出格式 输入格式: 一行两个整数 询问次数n,范围m 接下来n行,每行两个整数 l,r 表示区间 输出格式: 对 ...

  2. SIEVE 线性筛

    今天来玩玩筛 英文:Sieve 有什么筛? 这里介绍:素数筛,欧拉筛,约数个数筛,约数和筛 为什么要用筛? 顾名思义,筛就是要漏掉没用的,留下有用的.最终筛出来1~n的数的一些信息. 为什么要用线性筛 ...

  3. 【BZOJ3309】DZY Loves Math 莫比乌斯反演+线性筛(好题)

    [BZOJ3309]DZY Loves Math Description 对于正整数n,定义f(n)为n所含质因子的最大幂指数.例如f(1960)=f(2^3 * 5^1 * 7^2)=3, f(10 ...

  4. 【BZOJ4804】欧拉心算 莫比乌斯反演+线性筛

    [BZOJ4804]欧拉心算 Description 给出一个数字N Input 第一行为一个正整数T,表示数据组数. 接下来T行为询问,每行包含一个正整数N. T<=5000,N<=10 ...

  5. 莫比乌斯反演/线性筛/积性函数/杜教筛/min25筛 学习笔记

    最近重新系统地学了下这几个知识点,以前没发现他们的联系,这次总结一下. 莫比乌斯反演入门:https://blog.csdn.net/litble/article/details/72804050 线 ...

  6. 全网一定不是最好懂的C++线性筛素数

    Part 0:概念 先给几个概念(很重要): 合数:如果\(xy=z\text{且}x,y\text{为正整数}\),我们就说\(x,y\text{是}z\text{的合数}\) 素数:如果数\(a\ ...

  7. bzoj2693--莫比乌斯反演+积性函数线性筛

    推导: 设d=gcd(i,j) 利用莫比乌斯函数的性质 令sum(x,y)=(x*(x+1)/2)*(y*(y+1)/2) 令T=d*t 设f(T)= T可以分块.又由于μ是积性函数,积性函数的约束和 ...

  8. BZOJ 2693: jzptab [莫比乌斯反演 线性筛]

    2693: jzptab Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 1194  Solved: 455[Submit][Status][Discu ...

  9. BZOJ 2818: Gcd [欧拉函数 质数 线性筛]【学习笔记】

    2818: Gcd Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 4436  Solved: 1957[Submit][Status][Discuss ...

随机推荐

  1. Cadence 电源完整性仿真实践(一)

    软件版本号:Cadence 16.5 使用工具:Allegro PCB PI Option XL Power Integrity 使用资源:仿真实例下载地址:http://download.csdn. ...

  2. Amoeba是一个类似MySQL Proxy的分布式数据库中间代理层软件,是由陈思儒开发的一个开源的java项目

    http://www.cnblogs.com/xiaocen/p/3736095.html amoeba实现mysql读写分离 application  shang  2年前 (2013-03-28) ...

  3. Android TagFlowLayout完全解析 一款针对Tag的布局(转)

    一.概述 本文之前,先提一下关于上篇博文的100多万访问量请无视,博文被刷,我也很郁闷,本来想把那个文章放到草稿箱,结果放不进去,还把日期弄更新了,实属无奈. ok,开始今天的博文,今天要说的是Tag ...

  4. Android(java)学习笔记249:ContentProvider使用之获得系统联系人信息01

    1.系统联系人的数据库(3张最重要的表) (1)raw_contacts  联系人表        保存联系人的id   contact_id (2)data 数据表       保存联系人的数据 ( ...

  5. TCP总结

      TCP协议   <计算机网络>谢希仁 及笔记 TCP 的那些事儿(上):http://coolshell.cn/articles/11564.html TCP 的那些事儿(下):htt ...

  6. OD: ASLR

    ASLR,Address Space Layout Randomization,通过加载程序的时候不再使用固定的基址,从而干扰 shellcode 定位的一种保护机制,包括映像随机化.堆栈随机化.PE ...

  7. Examples_06_02(android)DDMS的data文件中没有显示文件。

    以前这里不显示music.cfg.通过Reset adb,就显示了. 查看虚拟机运行时里面的文件,进入adb.exe目录: E:\TDDOWNLOAD\adt-bundle-windows-x86-2 ...

  8. Asp.Net WebApi Action命名中已‘Get’开头问题

    ApiController 中的Action 命名已‘Get’开头,Post方法提交失败 场景: 1.action命名使用Get开头 /// <summary> /// 获取用户的未读消息 ...

  9. vim学习心得(一)——Cygwin下vim配置

    关于Vi有很多传说.其中最为著名的是: “Vi是编辑器之神,Emacs是神的编辑器” Emacs没有用过,但是Vi在Linux经常使用,所以,掌握好vi非常重要!!! Vim(Vi Improved) ...

  10. MYSQL id 自动加1

    个人心得 建立好表以后再进行修改总是容易出错 建议用sql语句进行创建表,定义相应的属性 CREATE TABLE USER( Id INTEGER PRIMARY KEY AUTO_INCREMEN ...