题目描述
输入
输出
样例输入
1 100
样例输出
8 2 4 6 12 24 36 48 60
数据范围限制
对于50%的数据,1<=l<=r<=500000。
对于70%的数据,保证最大的约数国王的约数的个数不大于1000。
对于100%的数据,1<=l<=r, 并且保证l,r在64位整型以内,最大的约数国王的约数的个数不大于200000。
设c(x)表示有x个约数的正整数。
c(x)是约数国王当且仅当c(x)
证明:(反证法)
假设c(x)>min(c(x+1),c(x+2)...c(x+k)),并且c(x)是约数国王,
设min(c(x+1),c(x+2)...c(x+k))是c(x+i),c(x)>c(x+i)但是x
证毕。
如果我们求出了所有的c(x),就可以用上述方法求出c(x)是不是约数国王。
那么问题就转化成怎么求出c(x);
我们设f[x][y]表示当前到了含有前x个质数,有y个约数的最小正整数。
f[x+1][y*(k+1)]=min(f[x+1][y*(k+1)],F[x][y]*p[x]k)
我们求出f数组之后,c[x]=min(f[i][x]);
那么c数组就求出来了,问题就解决了。
等这道题的人一定很多吧,这么坑的题(呵呵呵呵呵)
const
maxn=161281;
maxint=9223372036854775807;
zs:array[1..31]of longint=(2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,57,61,67,71,73,79,83,89,97,101,103,107,109,113,127);
var
f,q:array[1..13,1..170000]of qword;
l,r,sum,min:int64;
c,b:array[1..170000]of qword;
procedure dp;
var i,j,k,o:longint; p:qword;
begin
for i:=1 to 13 do
for j:=1 to 170000 do
f[i,j]:=maxint;
f[1,1]:=1;
f[1,2]:=2;
for i:=3 to 63 do
f[1,i]:=f[1,i-1]*2;
fillchar(q,sizeof(q),1);
for i:=1 to 12 do
for j:=1 to 81000 do
begin
p:=1;
if q[i,j]>maxn div j then o:=maxn div j
else o:=q[i,j];
for k:=1 to o do
begin
if maxint div zs[i+1]then break;
p:=p*zs[i+1];
if maxint div pthen break;
if f[i,j]*p1,j*(k+1)] then begin
f[i+1,j*(k+1)]:=f[i,j]*p;
q[i+1,j*(k+1)]:=k;
end;
end;
end;
end;
procedure main;
var i,j:longint;
begin
readln(l,r);
dp;
fillchar(c,sizeof(c),$7);
b[maxn+1]:=maxint;
for i:=maxn downto 1 do
begin
min:=maxint;
for j:=1 to 13 do
if f[j,i]then min:=f[j,i];
c[i]:=min;
if c[i]1] then b[i]:=c[i] else b[i]:=b[i+1];
end;
for i:=2 to maxn do
if (c[i]1])and(c[i]>=l)and(c[i]<=r) then inc(sum);
end;
procedure print;
var i,j:longint;
begin
for i:=2 to maxn do
if (c[i]>=l)and(c[i]<=r)and(c[i]1]) then write(c[i],' ');
end;
begin
assign(input,'king.in');reset(input);
assign(output,'king.out');rewrite(output);
main;
write(sum,' ');
print;
close(input); close(output);
end.