題目大意:給出一段範圍,求出這段範圍內的含有最多約數個數的那個數,輸出那個數和那個數的約數個數。
演算法:數論
題意說的很清楚,最簡單最直接的方法就是模擬了,但看一看那個資料規模。。1000000000。。且不說是一段區間,就是這個數字就已經夠大了,所以必須採用別的方法。
很容易想到了分解質因數的方法,乙個數x,如果x=p1^a1+p2^a2+p3^a3+p4^a4+...+pn^an(其中p1,p2,pn都是質因數),那麼它的約數個數就是(a1+1)*(a2+1)*...*(an+1)。(原理不再解釋了。)
既然這樣,我們就可以先篩個質數表,然後分別列舉質因數,例如:算出乙個2,兩個2,三個2。。。直到超過下界為止,然後把這些質因數的個數一乘就行了。
注意乘的時候只需要到根號,過了根號就會重複。
但是顯而易見的問題又來了,如果用這個質因數去組成的話最終落不到那個區間裡怎麼辦?怎麼樣才能很快的判斷出這點來呢?
我們可以比較(l-1) div number和r div number的大小,若這兩個數相等,那麼就說明從l到r這一段區間中沒有乙個數可以被我們列舉的number整除,因此可以直接剪掉。
然後又是乙個非常強大的剪枝,設from為當前列舉到的質因子,total是當前的最多的約數個數,那麼這次最多能剩下的因子數為p=log(from)(max/number),這些因子組成的約數個數最大為2^q。當前所能取到的最大約數個數就是total*2^q,如果這個數仍然無法超過最優解,那麼直接剪掉這一枝。
至此,本題基本上就可以完美的解決了。
ps:除了篩素是我寫的,別的都是別人的**。。。
program divisors;
const
maxprime=31622;
amount=3401;
var primes:array [0..amount] of longint;
l,r,number,max:longint;
procedure init;
begin
readln(l,r);
end;
procedure ss;
var i,j:longint;
get:array [2..maxprime] of boolean;
begin
fillchar(get,sizeof(get),true);
for i:=2 to maxprime do
begin
if get[i] then
begin
for j:=2 to maxprime div i do
get[i*j]:=false;
end;
end;
j:=0;
for i:=2 to maxprime do
begin
if get[i] then
begin
inc(j);
primes[j]:=i;
end;
end;
end;
procedure try_(from,tot,num,low,up:longint);
var x,y,n,m,i,j,t:longint;
begin
if num>=l then
begin
if (tot>max) or ((tot=max) and (nummax) then max:=tot shl 1;
for i:=from to amount do
begin
if primes[i]>up then exit
else
begin
j:=primes[i];
x:=low-1;
y:=up;
n:=num;
t:=tot;
m:=1;
while true do
begin
inc(m);
inc(t,tot);
x:=x div j;
y:=y div j;
if x=y then break;
n:=n*j;
try_(i+1,t,n,x+1,y);
end;
if totend;
end;
end;
procedure main;
begin
if (l=1) and (r=1) then
begin
max:=1;
number:=1;
endelse
begin
max:=2;
number:=l;
try_(1,1,1,l,r);
end;
end;
begin
assign(input,'divisors.in'); reset(input);
assign(output,'divisors.out'); rewrite(output);
init;
ss;main;
writeln('between ',l,' and ',r,', ',number,' has a maximum of ',max,' divisors.');
close(input); close(output);
end.
LuoguP1221 最多因子數
求區間 l,r 內約數個數最多的數和它的約數個數。這個題吧,乍一看確實不是很難,然後稍微一想,嗯,是個傻 題。這是唯一感受,不要問我為什麼。首先我們定義乙個函式 f x 表示 x 的約數個數。題目要求求出 l,r 中的 f x max 和這個數。首先最基本我們要知道每乙個數 data i 都乙個基本...
求1 N 的數中因子是最多的數及其最多的個數
問題描述 求1 n當中約數個數最多的數的個數。輸入格式 t組資料 每一組只有一行。這一行有乙個數n 1 n 10 18 input313 91000000000000000000 output139 103680 分析 直接暴力肯定會超時,那麼怎麼處理呢?根據唯一分解定理,我們可以知道乙個整數是可以...
X Y 因子數 因子和
本篇部落格講解一下 xy 的因子數,因子和的求解問題。首先根據算術基本定理 唯一分解定理 將 x 進行質因數分解 x p1 c1 p2 c2 pn cn則 x 的正因數可以表示為 0 bi ci 每個 bi 有 ci 1 種取法,根據乘法原理可得 x 的正因數個數為 為連乘積符號 c1 1 c2 1...