NYOJ 998
这道题是欧拉函数的使用,这里简要介绍下欧拉函数。
欧拉函数定义为:对于正整数n,欧拉函数是指不超过n且与n互质的正整数的个数。
欧拉函数的性质:1.设n = p1a1p2a2p3a3p4a4...pkak为正整数n的素数幂分解,那么φ(n) = n·(1-1/p1)·(1-1/p2)·(1-1/p3)···(1-1/pk)
2.如果n是质数,则φ(n) = n-1; 反之,如果p是一个正整数且满足φ(p)=p-1,那么p是素数。
3.设n是一个大于2 的正整数,则φ(n)是偶数
4.当n为奇数时,有φ(2n)=φ(n)
5.设m和n是互质的正整数,那么φ(mn)=φ(m)φ(n)
(1)可以根据性质1,写出计算欧拉函数值的程序: 复杂度为O(√n)
//直接求解欧拉函数
int euler(int n){ //返回euler(n)
int res=n;
for(int i=;i*i<=n;i++){
if(n%i==){
res=res/i*(i-);//先进行除法是为了防止中间数据的溢出
while(n%i==) n/=i;
}
}
if(n>) res=res/n*(n-);
return res;
}
(2)上面这种写法中,在for循环中选择i时,是顺序选择的。事实上性质1 中的p1、p2、p3、p4、...pk都是质数。如果在选择时,直接选择质数进行判断,那结果会优化很多。
可以先把50000以内的素数用筛法选出来并保存,以方便欧拉函数使用。这样,在不考虑筛法的时间复杂度,而单看欧拉函数,其复杂度变为O(x),x为√n以内素数的个数。
#include <cstring>
bool boo[];int p[]; void prim(){
//线性筛素数
memset(boo,,sizeof(boo));
boo[]=boo[]=;
int k=;
for(int i=;i<;i++){
if(!boo[i]) p[k++]=i;
for(int j=;j<k&&i*p[j]<;j++){
boo[i*p[j]] = ;
count++;
if(!(i%p[j])) break;
}
} } int phi(int n){
int rea = n;
for(int i=;p[i]*p[i]<=n;i++ ){ //对一些不是素数的可不用遍历
if(n%p[i]==){
rea = rea-rea/p[i];
while(n%p[i]==) n/=p[i];
}
}
if(n>) rea-=rea/n;
return rea;
}
(3)递推求欧拉函数
如果频繁的要使用欧拉函数值,就需要预先打表。复杂度约为O(nlnn)
//递推法打欧拉函数表
#define Max 1000001
int phi[Max];
void Init(){
for(int i=;i<=Max;i++) phi[i]=i;
for(int i=;i<=Max;i+=) phi[i]/=;
for(int i=;i<=Max;i+=)
if(phi[i]==i)
for(int j=i;j<=Max;j+=i)
phi[j]=phi[j]/i*(i-);//先进行除法是为了防止中间数据的溢出
}
应用:NYOJ 998 http://acm.nyist.net/JudgeOnline/problem.php?pid=998
这道题的精华如何将符合条件的gcd(x,n)表达出来:见代码 d*Euler(n/d) 中为什么乘以d的解释 。
然后是遍历一遍小于n的数,测试每个符合的数加起来即可。其实还可以更快,观察发现,在能够整除n的i里面,相对应的n/i也有相似的性质,这样以来只需要遍历到sqrt(n)即可。
网络摘抄代码如下:
#include<iostream>
#include<cstdio>
using namespace std; typedef long long LL;
LL Euler(LL n){
LL ans = n;
for(int i = ; i * i <= n; i++){
if(n % i == ){
ans = ans / i * (i-);
while(n % i == )
n /= i;
}
}
if(n > ) ans = ans / n * (n-);
return ans;
} int main(){
LL n,m;
while(cin>>n>>m){
LL ans = ;
for(int i = ; i * i <= n; i++){
if(n % i == ){
if(i >= m){
int d = i;
ans += d*Euler(n/d);
// 考虑 gcd(x,n) 1=<x<=n
//这个的由来是 gcd(x/d,n/d) = 1.如果我们取一个能让n/d取整数的d的取值,于是我们
//取到了n%i==0的i,于是 能够满足gcd(x,n) = d 的x的个数为Euler(n/d)个
//那么在该gcd = d 的情况下需要加到ans里面的d的个数就是Euler(n/d)个 ,所以有ans+=d*Euler(n/d) }
if(i * i != n && n / i >= m){
int d = n / i;
ans += d*Euler(n/d);
}
}
}
cout<<ans<<endl;
}
return ;
}
NYOJ 998的更多相关文章
- NYOJ 1007
在博客NYOJ 998 中已经写过计算欧拉函数的三种方法,这里不再赘述. 本题也是对欧拉函数的应用的考查,不过考查了另外一个数论基本定理:如何用欧拉函数求小于n且与n互质所有的正整数的和. 记eule ...
- NYOJ 333
http://www.cppblog.com/RyanWang/archive/2009/07/19/90512.aspx?opt=admin 欧拉函数 E(x)表示比x小的且与x互质的正整数的个数. ...
- NYOJ 99单词拼接(有向图的欧拉(回)路)
/* NYOJ 99单词拼接: 思路:欧拉回路或者欧拉路的搜索! 注意:是有向图的!不要当成无向图,否则在在搜索之前的判断中因为判断有无导致不必要的搜索,以致TLE! 有向图的欧拉路:abs(In[i ...
- nyoj 10 skiing 搜索+动归
整整两天了,都打不开网页,是不是我提交的次数太多了? nyoj 10: #include<stdio.h> #include<string.h> ][],b[][]; int ...
- 简答哈希实现 (nyoj 138 找球号2)
例题链接:http://acm.nyist.net/JudgeOnline/problem.php?pid=138 代码目的:复习哈希用 代码实现: #include "stdio.h&qu ...
- nyoj 284 坦克大战 简单搜索
题目链接:http://acm.nyist.net/JudgeOnline/problem.php?pid=284 题意:在一个给定图中,铁墙,河流不可走,砖墙走的话,多花费时间1,问从起点到终点至少 ...
- nyoj 170 网络的可靠性
题目链接:http://acm.nyist.net/JudgeOnline/problem.php?pid=170 思路:统计每个节点的度,将度为1的节点消去所需要的最少的边即为答案. 代码: #in ...
- nyoj 139 我排第几个--康拓展开
我排第几个 时间限制:1000 ms | 内存限制:65535 KB 难度:3 描述 现在有"abcdefghijkl”12个字符,将其所有的排列中按字典序排列,给出任意一种排列,说 ...
- 基于贪心算法的几类区间覆盖问题 nyoj 12喷水装置(二) nyoj 14会场安排问题
1)区间完全覆盖问题 问题描述:给定一个长度为m的区间,再给出n条线段的起点和终点(注意这里是闭区间),求最少使用多少条线段可以将整个区间完全覆盖 样例: 区间长度8,可选的覆盖线段[2,6],[1, ...
随机推荐
- C语言 · 高精度加法
问题描述 输入两个整数a和b,输出这两个整数的和.a和b都不超过100位. 算法描述 由于a和b都比较大,所以不能直接使用语言中的标准数据类型来存储.对于这种问题,一般使用数组来处理. 定义一个数组A ...
- 消息队列——RabbitMQ学习笔记
消息队列--RabbitMQ学习笔记 1. 写在前面 昨天简单学习了一个消息队列项目--RabbitMQ,今天趁热打铁,将学到的东西记录下来. 学习的资料主要是官网给出的6个基本的消息发送/接收模型, ...
- JavaScript性能优化
如今主流浏览器都在比拼JavaScript引擎的执行速度,但最终都会达到一个理论极限,即无限接近编译后程序执行速度. 这种情况下决定程序速度的另一个重要因素就是代码本身. 在这里我们会分门别类的介绍J ...
- Git Bash的一些命令和配置
查看git版本号: git --version 如果是第一次使用Git,你需要设置署名和邮箱: $ git config --global user.name "用户名" $ gi ...
- 使用CSS3实现一个3D相册
CSS3系列我已经写过两篇文章,感兴趣的同学可以先看一下CSS3初体验之奇技淫巧,CSS3 3D立方体效果-transform也不过如此 第一篇主要列出了一些常用或经典的CSS3技巧和方法:第二篇是一 ...
- 工厂方法模式——创建型模式02
1. 简单工厂模式 在介绍工厂方法模式之前,先介绍一下简单工厂模式.虽然简单工厂模式不属于GoF 23种设计模式,但通常将它作为学习其他工厂模式的入门,并且在实际开发中使用的也较为频繁. (1 ...
- 【原】AFNetworking源码阅读(二)
[原]AFNetworking源码阅读(二) 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 上一篇中我们在iOS Example代码中提到了AFHTTPSessionMa ...
- Node.js:dgram模块实现UDP通信
1.什么是UDP? 这里简单介绍下,UDP,即用户数据报协议,一种面向无连接的传输层协议,提供不可靠的消息传送服务.UDP协议使用端口号为不同的应用保留其各自的数据传输通道,这一点非常重要.与TCP相 ...
- ASP.Net MVC——使用 ITextSharp 完美解决HTML转PDF(中文也可以)
前言: 最近在做老师交代的一个在线写实验报告的小项目中,有这么个需求:把学生提交的实验报告(HTML形式)直接转成PDF,方便下载和打印. 以前都是直接用rdlc报表实现的,可这次牵扯到图片,并且更为 ...
- Android SDK 与API版本对应关系
Android SDK版本号 与 API Level 对应关系如下表: Code name Version API level (no code name) 1.0 API level 1 ( ...