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, ...
随机推荐
- [ 高并发]Java高并发编程系列第二篇--线程同步
高并发,听起来高大上的一个词汇,在身处于互联网潮的社会大趋势下,高并发赋予了更多的传奇色彩.首先,我们可以看到很多招聘中,会提到有高并发项目者优先.高并发,意味着,你的前雇主,有很大的业务层面的需求, ...
- TODO:Golang指针使用注意事项
TODO:Golang指针使用注意事项 先来看简单的例子1: 输出: 1 1 例子2: 输出: 1 3 例子1是使用值传递,Add方法不会做任何改变:例子2是使用指针传递,会改变地址,从而改变地址. ...
- HTTP常用状态码分析
不管是面试还是工作中,经常会碰到需要通过HTTP状态码去判断问题的情况,比如对于后台RD,给到前端FE的一个接口,出现502或者504 error错误,FE就会说接口存在问题,如果没有知识储备,那就只 ...
- 通过三次优化,我将gif加载优化了16.9%
WeTest 导读 现在app越来越炫,动不动就搞点动画,复杂的动画用原生实现起来挺复杂,如是就搞起gif播放动画的形式,节省开发成本. 背 景 设计同学准备给一个png序列,开发读取png序列, ...
- [笔记]kubernetes 无法启动问题
在启动kubernetes的时候报错误. ERROR: timed out for http://localhost:4001/v2/keys/ 原因是无法启动etcd, etcd 监听4001本地端 ...
- 分享两种实现Winform程序的多语言支持的解决方案
因公司业务需要,需要将原有的ERP系统加上支持繁体语言,但不能改变原有的编码方式,即:普通程序员感受不到编码有什么不同.经过我与几个同事的多番沟通,确定了以下两种方案: 方案一:在窗体基类中每次加载并 ...
- SQL Server2008R2 在windows8上安装,出现“兼容性”和 “执行未经授权的操作”的错误!
本人是windows8.1的操作系统,亲测安装成功 解决方法如下: 1.卸载干净sql Server2008r2,包括注册表内容,删除c盘下的安装路径! 2.关闭防火墙(这步很重要) 3.断开网络连接 ...
- asp.net mvc 验证码
效果图 验证码类 namespace QJW.VerifyCode { //用法: //public FileContentResult CreateValidate() //{ // Validat ...
- TemplateMethod(模块方法模式)
/** * 模块模式 * @author TMAC-J * 将一个完整的算法分离,分成不同的模块 * 用于有很多步骤的时候,可能以后这些步骤还会增加,把这些步骤分离 * 将有共性的部分放在抽象类中 * ...
- date命令
GNU的date提供+%s(小写s), 能打印出自1970-01-01 00:00:00到当前时间的秒数. 这可能大家都不陌生,但有两点需要注意: 1. %s存在于GNU扩展版本.像在solaris等 ...