我觉得我写不出更合适的题解了:http://www.2cto.com/kf/201412/359333.html
bzoj 2393
var
l,r,n,m :longint;
ans :int64;
a,b :array[0..1050] of int64;
flag :array[0..1050] of boolean;
i,j :longint;
function gcd(a,b:int64):int64;
begin
if b=0 then exit(a) else exit(gcd(b,a mod b));
end;
procedure dfs1(x:int64);
begin
if x>r then exit;
inc(n);
a[n]:=x;
dfs1(x*10+2);
dfs1(x*10+9);
end;
procedure dfs2(pos,f:longint;lcm:int64);
var
tt:int64;
begin
if b[pos]=0 then
begin
if (lcm xor 1<>0) then
inc(ans,f*(r div lcm-(l-1) div lcm));
exit;
end;
dfs2(pos+1,f,lcm);
tt:=lcm*b[pos] div gcd(lcm,b[pos]);
if tt>r then exit;
dfs2(pos+1,-f,tt);
end;
procedure sort(l,r:longint);
var
i,j:longint;
x,y:int64;
begin
i:=l; j:=r; x:=a[(l+r)>>1];
while (i<=j) do
begin
while (a[i]<x) do inc(i);
while (a[j]>x) do dec(j);
if (i<=j) then
begin
y:=a[i]; a[i]:=a[j]; a[j]:=y;
inc(i); dec(j);
end;
end;
if i<r then sort(i,r);
if j>l then sort(l,j);
end;
begin
read(l,r);
dfs1(2); dfs1(9);
sort(1,n);
for i:=1 to n do
for j:=i+1 to n do
if a[j] mod a[i]=0 then flag[j]:=true;
for i:=n downto 1 do //这里倒着循环跑着简直飞起
if not flag[i] then
begin
inc(m);
b[m]:=a[i];
end;
dfs2(1,-1,1);
writeln(ans);
end.
bzoj 1853
遇上题一样,注意数据范围是10^10,所以为了防止爆long long在乘的时候强转成double,确定不超的时候再乘
不知道为什么,bzoj上要开{$Q- I- S-}才能过,不然一直OLE ...
{$Q- I- S-}
var
l,r,n,m :int64;
i,j :longint;
flag :array[0..5010] of boolean;
a,b :array[0..5010] of int64;
ans :qword;
function gcd(a,b:int64):int64;
begin
if b=0 then exit(a) else exit(gcd(b,a mod b));
end;
procedure dfs1(x:int64);
begin
if x>r then exit;
inc(n);
a[n]:=x;
dfs1(x*10+6); dfs1(x*10+8);
end;
procedure dfs2(pos,f:longint;lcm:int64);
var
tt:int64;
begin
if b[pos]=0 then
begin
if (lcm xor 1 <>0) then
inc(ans,f*(r div lcm-(l-1) div lcm));
exit;
end;
dfs2(pos+1,f,lcm);
tt:=lcm div gcd(lcm,b[pos]);
if double(b[pos])*double(tt)>r then exit;
tt:=tt*b[pos];
dfs2(pos+1,-f,tt);
end;
procedure sort(l,r:longint);
var
i,j:longint;
x,y:int64;
begin
i:=l; j:=r; x:=a[(l+r)>>1];
while (i<=j) do
begin
while a[i]<x do inc(i);
while a[j]>x do dec(j);
if (i<=j) then
begin
y:=a[i]; a[i]:=a[j]; a[j]:=y;
inc(i); dec(j);
end;
end;
if i<r then sort(i,r);
if j>l then sort(l,j);
end;
begin
read(l,r);
dfs1(6); dfs1(8);
sort(1,n);
for i:=1 to n do
for j:=i+1 to n do
if (a[j] mod a[i]=0) then flag[j]:=true;
for i:=n downto 1 do
if not flag[i] then
begin
inc(m);
b[m]:=a[i];
end;
dfs2(1,-1,1);
writeln(ans);
end.
——by Eirlys