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 ...
随机推荐
- 两个时间相差多少 .net中的timespan应用
原文发布时间为:2008-10-31 -- 来源于本人的百度文章 [由搬家工具导入] using System;using System.Data;using System.Configuration ...
- vue slot 插槽备忘
老是记不住插槽咋回事 记录下来备忘 父组件 <tab><template slot="boy" slot-scope="test">{{ ...
- HTML-在canvas画图中,图片的线上链接已配置允许跨域后,仍然出错提示跨域,怎么解决?
这个问题我已经遇到了2次,第一次解决了后,第二次又遇到了,所以这次做个笔记,怕以后再次遇到 举例: 1.要实现的问题:我需要在canvas画布上画上我的微信头像 2.后台配置已经完成了允许我头像地址的 ...
- 浅谈HookSSDT和和Resume(恢复)SSDT
最近在学HookSSDT和针对Hook的ResumeSSDT,避免自己理解有所偏差,把它们写出来,希望大家不吝赐教.(虽然已经是过时了的技术,但是最起码了解其中的原理,嘿嘿嘿.) 转载注明出处:ht ...
- PAT 甲级 1045 Favorite Color Stripe(DP)
题目链接 Favorite Color Stripe 题意:给定$A$序列和$B$序列,你需要在$B$序列中找出任意一个最长的子序列,使得这个子序列也是$A$的子序列 (这个子序列的相邻元素可以重复) ...
- 域名缓存侦测(DNS Cache Snooping)技术
域名缓存侦测(DNS Cache Snooping)技术 在企业网络中,通常都会配置DNS服务器,为网络内的主机提供域名解析服务.这些DNS不仅解析自己的私有域名,还会用递归方式,请求公网的DNS解析 ...
- CDOJ 1171 两句话题意
题目链接:http://acm.uestc.edu.cn/#/problem/show/1171 题解: 这道题应该从gcd出来的值入手. 我们要求所有子集的gcd的和 首先我们先统计一下每个数字出现 ...
- 随笔:Golang 时间Time
先了解下time类型: type Time struct { // sec gives the number of seconds elapsed since // January 1, year 1 ...
- Python之Django-part 1
python manage.py syncdb 在django1.7已经被取代了:用python manage.py migrate 代替来移动库: 删除.卸载django 在cd /usr/lo ...
- CA认证原理以及实现(下)
在上述的文章后了解到原理之后,我们这篇文章来进行CA的搭建. OPEN SSL 环境搭建在基础原理中我们提到了两种认证服务,单项认证服务和双向认证服务,我们就以双向认证服务举例说明.OpenSSL是一 ...