题目链接:传送门

题目需求: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. win7 安装 VMware 出错解决办法

    win7旗舰版安装VMware,安装过程中发生了如下错误.系统提示:“You may not install this product in the root directory of any dri ...

  2. centos7 安装zookeeper 集群

    data 创建myid  设置1 zookeeper默认端口2181  同步端口 20881 和 30881 设置zoo.cfg文件

  3. [Extjs] Ext4 Ext.grid.Panel 分页实现(mybatis 分页插件-PageHelper 使用)

    先看图: 页面js代码: var userStore=Ext.create('Ext.data.Store', { storeId:'userStore', fields:['uname', 'ema ...

  4. GIS-013-Cesium Terrain 数据生成

    一.Python 1.修改Python脚本文件 if __name__=='__main__': #sys.argv = ['F:\\000_Terrain\\T7-gdal2srtmtiles-de ...

  5. VC++第三方库配置-OpenSpirit 4.2.0 二次开发

    在VS中右击项目,点击属性 1.配置属性--常规--输出目录:Windows\VS2010\debug\ 2.配置属性--常规--中间目录:Windows\VS2010\debug\ 3.配置属性-- ...

  6. linux解压和压缩

    1.压缩命令: 命令格式:tar  -zcvf   压缩文件名.tar.gz   被压缩文件名 可先切换到当前目录下.压缩文件名和被压缩文件名都可加入路径. 2.解压缩命令: 命令格式:tar  -z ...

  7. 查看进程动态:top

    top命令用于查看进程动态,即进程使用系统资源的情况,常见用法如下: [root@localhost ~]$ top # 动态查看进程使用资源的情况,每三秒刷新一次 [root@localhost ~ ...

  8. 关于C中I/O缓冲区的解释

    用户程序调用C标准I/O库函数读写文件或设备,而这些库函数要通过系统调用把读写请求传给内核,最终由内核驱动磁盘或设备完成I/O操作.C标准库为每个打开的文件分配一个I/O缓冲区以加速读写操作,通过文件 ...

  9. Swift-Debug下打印函数名和行数

    1.Build Settings ->搜索 Swift compiler -> OTHER_SWIFT_FLAGS = -D DEBUG 2.设置DEBUG函数 配置好后就可以愉快的进行调 ...

  10. MUI 单图片压缩上传(拍照+系统相册): 选择立即上传

    1 html 部分 <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> < ...