对于100%的数据,1<=l<=r, 并且保证l,r在64位整型以内,最大的约数国王的约数的个数不大于200000。
设c(x)表示有x个约数的正整数。
c(x)是约数国王当且仅当c(x)<min(c(x+1),c(x+2)...c(x+k))(k趋向于无穷大)
证明:(反证法) 假设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<x+i,所以c(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]<p then break; p:=p*zs[i+1]; if maxint div p<f[i,j] then break; if f[i,j]*p<f[i+1,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]<min then min:=f[j,i]; c[i]:=min; if c[i]<b[i+1] then b[i]:=c[i] else b[i]:=b[i+1]; end; for i:=2 to maxn do if (c[i]<b[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]<b[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.