BZOJ 2820: YY的GCD [莫比乌斯反演]【学习笔记】
2820: YY的GCD
Time Limit: 10 Sec Memory Limit: 512 MB
Submit: 1624 Solved: 853
[Submit][Status][Discuss]
Description
Input
Output
Sample Input
10 10
100 100
Sample Output
2791
HINT
T = 10000
N, M <= 10000000
和bzoj2705很像http://www.cnblogs.com/candy99/p/6200745.html
但是n和m不同,不能使用直接欧拉函数的方法
参考:http://blog.csdn.net/acdreamers/article/details/8542292 && popoqqq课件
和上一题相同的函数:
为满足
且
和
的
的对数
为满足
且
和
的
的对数
显然,反演后得到
可以枚举每一个质数,套用上一题的做法,p相当于k,d*p也就是p的倍数了...很像上一题我WT1中的式子
其实d只要枚举到min(n,m)/p
然而复杂度承受不了,大约n/logn*sqrt(n)
我们设,那么继续得到
为什么这么做呢?因为这样之后发现F函数与p和d无关了,(要不然枚举p和d也是枚举了T)
可以提到前面,剩下的那一块可以处理前缀和做到O(1),前面再用除法分块,做到O(sqrt(n))
WT:
如何求g(T)=Σ{p|T && isprime(p)}miu(T/p)
法1.
只需要枚举每个素数,将他的倍数的g更新就可以了
由于有1/1+1/2+1/3+...+1/n=O(logn)这个结论 因此每个质数枚举时是均摊O(logn)的(*n后好想,是nlogn,但是质数只有n/logn个)
而质数恰好有O(n/logn)个 因此暴力枚举就是O(n)的
法2.
线性筛
g[i*p[j]]
当p[j]|i时结果显然为miu(i)
否则考虑mu(i*p[j]/pp),当p[j]=pp时为mu[i],p[j]!=pp时的所有的和就是-g(i),所以总的结果为mu(i)-g(i)
枚举质数 4176ms
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
typedef long long ll;
const int N=1e7+;
inline int read(){
char c=getchar();int x=,f=;
while(c<''||c>''){if(c=='-')f=-; c=getchar();}
while(c>=''&&c<=''){x=x*+c-''; c=getchar();}
return x*f;
}
int n,m;
bool notp[N];
int p[N],mu[N],g[N];
void sieve(){
mu[]=;
for(int i=;i<N;i++){
if(!notp[i]) p[++p[]]=i,mu[i]=-;
for(int j=;j<=p[]&&i*p[j]<N;j++){
notp[i*p[j]]=;
if(i%p[j]==){
mu[i*p[j]]=;
break;
}
mu[i*p[j]]=-mu[i];
}
} for(int j=;j<=p[];j++)
for(int i=p[j];i<N;i+=p[j])
g[i]+=mu[i/p[j]];
for(int i=;i<N;i++) g[i]+=g[i-];
}
ll cal(int n,int m){
if(n>m) swap(n,m);
ll ans=;int r;
for(int i=;i<=n;i=r+){
r=min(n/(n/i),m/(m/i));
ans+=(ll)(g[r]-g[i-])*(n/i)*(m/i);
}
return ans;
}
int main(int argc, const char * argv[]) {
sieve();
int T=read();
while(T--){
n=read();m=read();
printf("%lld\n",cal(n,m));
}
return ;
}
线性筛:3328ms
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
typedef long long ll;
const int N=1e7+;
inline int read(){
char c=getchar();int x=,f=;
while(c<''||c>''){if(c=='-')f=-; c=getchar();}
while(c>=''&&c<=''){x=x*+c-''; c=getchar();}
return x*f;
}
int n,m;
bool notp[N];
int p[N],mu[N],g[N];
void sieve(){
mu[]=;
for(int i=;i<N;i++){
if(!notp[i]) p[++p[]]=i,mu[i]=-,g[i]=;
for(int j=;j<=p[]&&i*p[j]<N;j++){
notp[i*p[j]]=;
if(i%p[j]==){
mu[i*p[j]]=;
g[i*p[j]]=mu[i];
break;
}
mu[i*p[j]]=-mu[i];
g[i*p[j]]=mu[i]-g[i];
}
}
for(int i=;i<N;i++) g[i]+=g[i-];
}
ll cal(int n,int m){
if(n>m) swap(n,m);
ll ans=;int r;
for(int i=;i<=n;i=r+){
r=min(n/(n/i),m/(m/i));
ans+=(ll)(g[r]-g[i-])*(n/i)*(m/i);
}
return ans;
}
int main(int argc, const char * argv[]) {
sieve();
int T=read();
while(T--){
n=read();m=read();
printf("%lld\n",cal(n,m));
}
return ;
}
BZOJ 2820: YY的GCD [莫比乌斯反演]【学习笔记】的更多相关文章
- [BZOJ 2820] YY的gcd(莫比乌斯反演+数论分块)
[BZOJ 2820] YY的gcd(莫比乌斯反演+数论分块) 题面 给定N, M,求\(1\leq x\leq N, 1\leq y\leq M\)且gcd(x, y)为质数的(x, y)有多少对. ...
- Bzoj 2820: YY的GCD(莫比乌斯反演+除法分块)
2820: YY的GCD Time Limit: 10 Sec Memory Limit: 512 MB Description 神犇YY虐完数论后给傻×kAc出了一题给定N, M,求1<=x& ...
- bzoj 2820 YY的GCD 莫比乌斯反演
题目大意: 给定N, M,求1<=x<=N, 1<=y<=M且gcd(x, y)为质数的(x, y)有多少对 这里就抄一下别人的推断过程了 后面这个g(x) 算的方法就是在线性 ...
- bzoj 2820 YY的GCD - 莫比乌斯反演 - 线性筛
Description 神犇YY虐完数论后给傻×kAc出了一题给定N, M,求1<=x<=N, 1<=y<=M且gcd(x, y)为质数的(x, y)有多少对kAc这种 傻×必 ...
- BZOJ 2820: YY的GCD 莫比乌斯反演_数学推导_线性筛
Code: #include <cstdio> #include <algorithm> #include <cstring> #include <vecto ...
- BZOJ 2820 YY的GCD ——莫比乌斯反演
我们可以枚举每一个质数,那么答案就是 $\sum_{p}\sum_{d<=n}\mu(d)*\lfloor n / pd \rfloor *\lfloor m / pd \rfloor$ 直接做 ...
- 【莫比乌斯反演】关于Mobius反演与gcd的一些关系与问题简化(bzoj 2301 Problem b&&bzoj 2820 YY的GCD&&BZOJ 3529 数表)
首先我们来看一道题 BZOJ 2301 Problem b Description 对于给出的n个询问,每次求有多少个数对(x,y),满足a≤x≤b,c≤y≤d,且gcd(x,y) = k,gcd( ...
- 【刷题】BZOJ 2820 YY的GCD
Description 神犇YY虐完数论后给傻×kAc出了一题给定N, M,求1<=x<=N, 1<=y<=M且gcd(x, y)为质数的(x, y)有多少对kAc这种傻×必然 ...
- SPOJ PGCD 4491. Primes in GCD Table && BZOJ 2820 YY的GCD (莫比乌斯反演)
4491. Primes in GCD Table Problem code: PGCD Johnny has created a table which encodes the results of ...
随机推荐
- ASP.NET MVC5+EF6+EasyUI 后台管理系统--任务调度系统解析
1.任务主界面.任务可以被挂起,启动,和删除.来自著名Quartz扩展 2.任务可以是执行的SQL命令,存储过程,或者是一个后台方法 3.极其复杂的调度任务,循环次数,可以自行设置.并可以间隔执行,比 ...
- ASP.NET Core官方计划路线及需要废除的一些Framework技术
概述 下面是 ASP.NET Core的时间表和路线图. 注意日期和特性都可能更改. 作为.NET Core这么大的一个项目,很难准确预测每一个计划的是否有变动. 即便如此,我们还是计划公开和透明的实 ...
- 利用KD树进行异常检测
软件安全课程的一次实验,整理之后发出来共享. 什么是KD树 要说KD树,我们得先说一下什么是KNN算法. KNN是k-NearestNeighbor的简称,原理很简单:当你有一堆已经标注好的数据时,你 ...
- python学习笔记(基础三:if else流程判断、while循环、for循环)
if else流程判断 getpass在pycharm中无法使用,在命令行窗口中进入python环境可以使用. import getpassusername = input("usernam ...
- Struts2框架简介和示例
struts2框架 Struts2是java web的框架,在Java Web开发中,表示层框架,其核心是通过扩展Servlet来帮助处理http请求. Struct2的基本流程 Struct2的框架 ...
- 用jmeter通过ssl验证访问https
找了一个支付宝的网站尝试.https://memberprod.alipay.com/account/reg/index.htm 我用的是chrome,点这个小锁 如果是IE也可以在网页上右键,属性, ...
- Regular Express正则表达式基础
一. 创建一个正则表达式RegExp,有两种方式如下图所示 二. 创建一个正则表达式RegExp详述说明 1.构造函数 //RegExp 是js中一个内置的对象,是正则表达式的缩写 var reg = ...
- 一分钟搞定AlloyTouch图片轮播组件
轮播图也涉及到触摸和触摸反馈,同时,AlloyTouch可以把惯性运动打开或者关闭,并且设置min和max为运动区域,超出会自动回弹. 除了一般的竖向滚动,AlloyTouch也可以支持横向滚动,甚至 ...
- 在js中为图片的src赋值时,src的值不能在开头用 破浪号~
<img id="aa" src="~/Content/Manager/no01.png" /> document.getElementById(& ...
- H5 meta小结
<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1, ...