题目链接:传送门

题目需求:Given integers N and M, how many integer X satisfies 1<=X<=N and (X,N)>=M.(2<=N<=1000000000, 1<=M<=N),

题目解析:

求(X,N),不用想要分解N的因子,分解方法如下,我一开始直接分解for(int i=2;i<=n/2;i++),这样的话如果n==10^9,那么直接超时,因为这点失误直接浪费了一中午

的时间,要这么分解for(int i=2;i*i<=n;i++)具体请在代码里面看,然后开始求(X,N)>=M。

这才是核心:

要求有多少个 i 满足gcd(i, N) = d(1<=i<=N)
如果gcd(i, N) = d,则gcd(i/d, N/d) = 1
由于i <= N,所以 i/d <= N/d,转化为求多少个不大于N/d的数与N/d互质,而这就是欧拉函数
所以有phi(N/d)个 i 满足gcd(i, N) = d,所以求gcd(i,N)>=M,就是求N的因子中大于等于M的欧拉函数值,

即gcd(N/d1)+gcd(N/d2)+...+gcd(N/dn),其中di>=M,且为N的因子。

直接写:(都是15ms,这是后台数据的问题,数据多了肯定还是打表快)

#include <iostream>
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <math.h>
typedef __int64 ll;
using namespace std;
ll n,m,sum,top,key,M,coun,i;
int f[];
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
sum=;
top=;
scanf("%I64d%I64d",&n,&m);
for(i=; i*i<n; i++)
{
if(n%i==)
{
f[top++]=i;
f[top++]=n/i;
}
}
if(i*i==n)//千万别忘了这一句,如16=4*4
{
f[top++]=i;
}
sort(f,f+top);
key=-;
for(i=; i<top; i++)
{
if(f[i]>=m)
{
key=i;
break;
}
}
if(key==-)
{
printf("1\n");
continue;
}
for(i=key; i<top; i++)
{
M=n/f[i];
coun=n/f[i];
for(ll z=; z*z<=M; z++)
{
if(M%z==)
{
coun-=coun/z;
M/=z;
while(M%z==)
M/=z;
}
}
if(M!=) coun-=coun/M;
sum+=coun;
}
printf("%I64d\n",sum);
}
return ;
}

一部分欧拉值打表:

#include <iostream>
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <math.h>
typedef __int64 ll;
using namespace std;
ll n,m,sum,top,key,i;
int phi[],f[];
void init()
{
memset(phi,,sizeof(phi));
phi[]=;
for(int i=; i<=; i++)
{
if(!phi[i])
{
for(int j=i; j<=; j=j+i)
{
if(!phi[j]) phi[j]=j;
phi[j]-=phi[j]/i;
}
}
}
}
int main()
{
int T;
scanf("%d",&T);
init();
while(T--)
{
sum=;
top=;
scanf("%I64d%I64d",&n,&m);
for(i=; i*i<n; i++)
{
if(n%i==)
{
f[top++]=i;
f[top++]=n/i;
}
}
if(i*i==n)
{
f[top++]=i;
}
sort(f,f+top);
for(i=; i<top; i++)
{
if(f[i]>=m)
{
key=i;
break;
}
}
if(key==-)
{
printf("1\n");
continue;
}
for(ll i=key; i<top; i++)
{
if(n/f[i]<=)
{
sum+=phi[n/f[i]];
continue;
}
ll M=n/f[i];
ll coun=n/f[i];
for(ll z=; z*z<=M; z++)
{
if(M%z==)
{
coun-=coun/z;
M/=z;
while(M%z==)
M/=z;
}
}
if(M!=) coun-=coun/M;
sum+=coun;
}
printf("%I64d\n",sum);
}
return ;
}

大神博客:http://hi.baidu.com/bg1995/item/ef25e3261f584053c38d59a8

HDU2588:GCD(欧拉函数的应用)的更多相关文章

  1. hdu2588 gcd 欧拉函数

    GCD Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submiss ...

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

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

  3. POJ 2773 Happy 2006【GCD/欧拉函数】

    根据欧几里德算法,gcd(a,b)=gcd(a+b*t,b) 如果a和b互质,则a+b*t和b也互质,即与a互质的数对a取模具有周期性. 所以只要求出小于n且与n互质的元素即可. #include&l ...

  4. HDU 2588 GCD (欧拉函数)

    GCD Time Limit: 1000MS   Memory Limit: 32768KB   64bit IO Format: %I64d & %I64u Submit Status De ...

  5. Bzoj-2818 Gcd 欧拉函数

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2818 题意:给定整数N,求1<=x,y<=N且Gcd(x,y)为素数的数对(x ...

  6. BZOJ2818: Gcd 欧拉函数求前缀和

    给定整数N,求1<=x,y<=N且Gcd(x,y)为素数的数对(x,y)有多少对. 如果两个数的x,y最大公约数是z,那么x/z,y/z一定是互质的 然后找到所有的素数,然后用欧拉函数求一 ...

  7. HDU 1695 GCD 欧拉函数+容斥定理

    输入a b c d k求有多少对x y 使得x在a-b区间 y在c-d区间 gcd(x, y) = k 此外a和c一定是1 由于gcd(x, y) == k 将b和d都除以k 题目转化为1到b/k 和 ...

  8. HDU 1695 GCD 欧拉函数+容斥定理 || 莫比乌斯反演

    GCD Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submiss ...

  9. HDU 1695 GCD (欧拉函数,容斥原理)

    GCD Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submis ...

  10. hdu 1695 GCD (欧拉函数+容斥原理)

    GCD Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submiss ...

随机推荐

  1. 记录下一个自己不常用的关键字-yield

    yield 这个关键字 一直很少用,也不知道具体用途.按照习惯就查询了下MSDN. 意思大致是这样的:在迭代器块中用于向枚举数对象提供值或发出迭代结束信号 表现形式:1. yield return & ...

  2. mysql读写分离实战

    一个完整的MySQL读写分离环境包括以下几个部分: 应用程序client database proxy database集群 在本次实战中,应用程序client基于c3p0连接后端的database ...

  3. redisTools-IdGenerator

    public class IdGenerator : RedisToolBase { //redis客户端对象 private static readonly NedisClient client = ...

  4. 交换a、b的值temp = a; a = b; b = temp;比a = a^b;b = a^b;a = a^b;快

    先看代码,交换a.b的值十亿次 <span style="font-size:14px;"> int a=222; int b=111; int size = 1000 ...

  5. Linux上Nginx部署配置--二级域名配置

    http://www.cnblogs.com/yaunion/archive/2013/03/16/2962385.html http://blog.csdn.net/LBinin/article/d ...

  6. js 对象引用传值

    1)当变量是一个对象(例如:{}或[]),使用 a = b = {} 这种形式传值的话,会变成会用传值,修改 a 时 b 会相应变化,修改 b 时 a 也一样会相应变化 var a = b = {}; ...

  7. Android 手机随音乐振动

    想到做一个Android软件可以在播放音乐的同时手机在音量或者音调高的时候振动一下. 等我熟练Android的时候试试...

  8. php第一例

    参考 例子 https://www.cnblogs.com/chinajins/p/5622342.html 配置多个网站 https://blog.csdn.net/win7system/artic ...

  9. django restframwork教程之Request和Response

    从这一篇文章开始,我们会覆盖整个REST framwork框架的核心,接下来让我们介绍一些基础的构建块 Request 对象 REST framework 引入了一个扩展HttpRequest的请求对 ...

  10. AndroidのUI布局之layout weight

    <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android=&quo ...