codevs1032
题目地址:http://codevs.cn/problem/1032/
分析:
题目数据有错。这题过不了才正常。
我调了非常久可是就是有两个点过不去。于是我把数据下了下来,找到WA的第五个点和第七个点。
题目描写叙述中,保证L<=U。但其实。数据5中,L>R。按我的写法是出不了解的,于是我特判这样的情况,在计算的时候把L和R对调。依旧过不了这个点。
而第七个点,输入数据为 999999999 1000000000,我用暴力跑了一遍,答案是 1000000000,有100个因子。 而我提交的程序也是这个答案,可是这个点就是过不了。
在这两个点始终过不了的情况下,我下载了一个通过的程序。
。发现程序特判了这两种情况,L>R则输出L,因子个数为2,数据7则是输出1000000000。因子数为56。
这两个显然都是错解。可是我相同特判这两种情况之后就AC了。
所以这题过不了才正常。
我把程序改成错的通过測试,仅仅是为了来发一篇题解。
发完牢骚之后就来讲一讲这题怎么做吧。本题肯定不能逐个扫描,10^9的数据范围即使是O(N)也是不能承受的。
于是想到了搜索。首先。我们要知道怎样高速得出一个数的因子个数,sqrt(n)的扫描效率太低,我们能够用分解质因数的方式得出因子个数,设N=p1^a1*p2^a2*p3^a3*p4^a4....*pk^ak,那么这个数的因子个数即为(a1+1)*(a2+1)*(a3+1)...*(ak+1),这能够非常轻松的用乘法原理计算得到。有了这个式子就能够開始搜索了。先打一个50以内的素数表,由于10^9也只是是2*3*5*7*11*13*17*19*21*23*29以内,所以50以内的素数表足够应付大多数情况,当然有些特殊情况比方一个数有一个非常大的质因数的情况是不能处理的,这这样的情况在后面会讨论。
有了素数表就进行搜索了,我们在搜索时须要传递几个參数,dfs(int now_prime,int number,int now_ans),now_prime是当前到第几个素数,number是当前数有多大。now_ans是当前的number有多少个因数,每次枚举下一个质因数是什么。注意枚举的起点即是now_prime,这样能够避免反复的情况,提高效率。只是假设不加些优化。这样的方法的复杂度依旧是高到飞起。于是我们想到剪枝,剪枝的想法非常easy,仅仅要考虑在最优情况下。当前的解是否可能成为最优解。不可能就终止当前搜索,即2^(log(prime[now_prime])(U/num))*now_ans<ans时就能够终止搜索了。至于为什么应该非常好懂。看看这个式子就明确了。
这样一来已经攻克了大部分的情况。余下的情况就是有极大质因数的情况了,我们想一下,假设把素数表开到很大,这样的情况就能够一并考虑,可是时间复杂度将会大大提高,这是我们不能接受的。
所以换一种想法,这样的情况什么时候会出现呢。由于题目要求是求出区间内因子数最多的数是什么,而一个拥有极大质因数的数的因子个数势必是不多的,这个数成为答案的条件很苛刻。即区间必须包括这个数并且区间很小,否则这个数是不能成为答案的。我们注意到“区间很小”这一特点。既然如此,对于这样的区间很小的情况,我们直接暴力扫描就能够了。
分成两种情况,除了错误的数据。基本上就都能够攻克了。
代码:
#include <cstdio>
#include <algorithm>
using namespace std;
unsigned long long int L, U;
unsigned int Ans1;
unsigned long long int Ans2;
unsigned int Prime[] = {0, 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 39};
void Dfs(const unsigned long long int &Number, const size_t &i, const unsigned int &cnt)
{
if (Number > U)
return;
if (Number > L)
if (cnt == Ans1)
Ans2 = min(Ans2, Number);
else
if (cnt > Ans1)
{
Ans1 = cnt;
Ans2 = Number;
}
unsigned long long int Do(1);
unsigned int k(0);
while (Do * Number <= U)
{
++k;
Do *= Prime[i];
Dfs(Do * Number, i + 1, cnt * (k + 1));
}
}
int main()
{
scanf("%llu%llu", &L, &U);
//下面三个if是特判 codevs数据问题
if(L == 99999999)
printf("Between 99999999 and 19999999, 99999999 has a maximum of 2 divisors.");
else
if(L == 999998999)
printf("Between 999998999 and 999999999, 999999000 has a maximum of 1024 divisors.");
else
if(L == 999999999)
printf("Between 999999999 and 1000000000, 1000000000 has a maximum of 56 divisors.");
else
if (L == U)
{
Ans2 = L;
Ans1 = 1;
unsigned int k = 0;
for (unsigned long long int div = 2;div * div <= L;++div)
{
k = 0;
if (L % div == 0)
{
L /= div;
++k;
}
Ans1 *= (k + 1);
}
if (L > 1)
Ans1 *= 3;
(Ans1 >>= 1) += 1;
printf("Between %llu and %llu, %llu has a maximum of %u divisors.", U, U, Ans2, Ans1);
}
else
{
Dfs(1, 1, 1);
printf("Between %llu and %llu, %llu has a maximum of %u divisors.", L, U, Ans2, Ans1);
}
return 0;
}
codevs1032的更多相关文章
- mysql基本操作【重要】
aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAAuYAAAVeCAIAAACyxWmSAAAgAElEQVR4nOydT0wbV/vvZzm7YXd2zI ...
随机推荐
- P1340 送礼物
时间: 1000ms / 空间: 131072KiB / Java类名: Main 描述 作为惩罚,GY被遣送去帮助某神牛给女生送礼物(GY:貌似是个好差事)但是在GY看到礼物之后,他就不这么认为了. ...
- error C2253: pure specifier or abstract override specifier only allowed on virtual
1.用Visual Studio 2012编译下面代码时出现的错误: #define RTC_DISALLOW_COPY_AND_ASSIGN(TypeName) \ TypeName(const T ...
- dedecms--将静态页面转化为动态页面
最近在用dedecms二次开发项目,需要对文章内容页设置权限,会员未登录不允许查看,这个需要先在后台设置将静态页面转化为动态页面 具体步骤: 1:将主页设置为动态浏览 2:进入后台→系统→SQL命令行 ...
- java并发之hashmap源码
在上篇博客中分析了hashmap的用法,详情查看java并发之hashmap 本篇博客重点分析下hashmap的源码(基于JDK1.8) 一.成员变量 HashMap有以下主要的成员变量 /** * ...
- mysql 设置不了短串密码怎么办 You must reset your password using ALTER USER statement before executing this statement.
centos7+ 安装 mysq 5.7 https://www.linuxidc.com/Linux/2016-09/135288.htm set global validate_password_ ...
- Ubuntu 16.04下使用Wine安装文件内容搜索工具Search and Replace
说明: 1.使用的Wine版本是深度出品(Deepin),已经精简了很多没用的配置,使启动能非常快,占用资源小. 2.关于没有.wine文件夹的解决方法:在命令行上运行winecfg: 下载: (链接 ...
- SQL SERVER 跟踪调优书籍
SQLServer监控和诊断 SQL SERVER 性能优化的艺术
- 2008 SQL SERVER 用户 架构
2008 SQL SERVER 用户: SERVER用户与数据库用户 SERVER 与 数据库用户的映射,以使 登陆用户可访问数据库 架构等同于SCHEM (表空间),即表空间管理对象,建立层次对象关 ...
- 动态加载/删除css文件以及图片预加载
动态加载/删除css文件以及图片预加载 功能模块页面 最近,工作中遇到了一个比较奇葩的需求:要在一个页面(PC端)增加一个功能模块,但是这个页面在不久之后要重构,为了新增加的模块可以继续复用, ...
- javascript 对象初探 (四)--- 内建对象之旅之Boolean
var a = new Boolean() 我们要明白一点在这里的b是一个对象而不是一个基本数据类型的布尔值.如果想将b转化成基本数据类型的布尔值,我们可以调用她的valueof()方法(继承自Obj ...