Назад к лучшим решениям Status: AC, problem ZSQRT2, contest ZEL07. By jedi_knight_ (Ivan Popelyshev), 2007-02-11 14:18:27.
{$IFDEF ONLINE_JUDGE}
{$ASMMODE Intel}
{$ELSE}
{$APPTYPE CONSOLE}
{$ENDIF}
const
base10=4;
base=10000;
ndigs2=20;
ndigs=1 shl ndigs2;
mask=1000;
iter=2000000;
type
int=longint;
real=double;
tlong=array [0..ndigs+1] of int;
tcomp=record re,im:real;end;
tfur=array[0..ndigs-1] of tcomp;
var
a,b,c:tlong;
aa,bb,cc: tfur;
rev:array[0..ndigs-1]of int;
len,len2:int;
cl:int;
procedure add(var a, b: tlong;var c: tlong);
var
i,t:int;
begin
t:=0;
for i:=0 to 2*cl do
begin
t:=t+a[i]+b[i];
c[i]:=t mod base;
t:=t div base;
end
end;
procedure sub(var a,b:tlong;var c:tlong);
var
i,t:int;
begin
t:=0;
for i:=0 to 2*cl do
begin
t:=t+a[i]-b[i];
if (t<0) then
begin
c[i]:=t+base;
t:=-1;
end else
begin
c[i]:=t;
t:=0;
end
end
end;
procedure calc;
var i,j,k:int;
begin
j:=0;
for i:=0 to len-2 do
begin
rev[i]:=j;
k:=len;
repeat
k:=k shr 1;
j:=j xor k;
until (j and k)>0;
end;
rev[len-1]:=len-1;
end;
procedure copy1(var source:tlong; var dest: tfur);
var
i: int;
begin
for i:=0 to len-1 do
begin
dest[i].re:=source[rev[i]];
dest[i].im:=0;
end
end;
type
tct=array of tcomp;
var
tb:array[0..21] of tct;
procedure init;
var
i,j:int;
sina,cosa:real;
begin
for i:=0 to 20 do
begin
setlength(tb[i],1 shl i);
cosa:=cos(pi/(1 shl i));
sina:=sin(pi/(1 shl i));
for j:=0 to (1 shl i)-1 do
begin
if (j mod mask)=0 then
begin
tb[i][j].re:=cos((pi*j)/(1 shl i));
tb[i][j].im:=sin((pi*j)/(1 shl i));
continue;
end;
tb[i][j].re:=tb[i][j-1].re*cosa-tb[i][j-1].im*sina;
tb[i][j].im:=tb[i][j-1].re*sina+tb[i][j-1].im*cosa;
end
end
end;
procedure fur(var res:tfur);
var
i,j,j1,k,l:int;
c2:tcomp;
cosa, sina: real;
v:tct;
begin
for i:=1 to len2 do
begin
j:=1 shl (i-1);
j1:=1 shl i;
k:=0;
v:=tb[i-1];
while (k<len) do
begin
for l:=0 to j-1 do
begin
cosa:=v[l].re;
sina:=v[l].im;
c2.re:=res[k+l+j].re*cosa-res[k+l+j].im*sina;
c2.im:=res[k+l+j].im*cosa+res[k+l+j].re*sina;
res[k+l+j].re:=res[k+l].re-c2.re;
res[k+l+j].im:=res[k+l].im-c2.im;
res[k+l].re:=res[k+l].re+c2.re;
res[k+l].im:=res[k+l].im+c2.im;
end;
inc(k,j1);
end
end
end;
procedure mult1(var aa, bb, res: tfur);
var
i:int;
c: tcomp;
begin
for i:=0 to len-1 do
begin
c.re:=(aa[i].re*bb[i].re-aa[i].im*bb[i].im);
c.im:=(aa[i].im*bb[i].re+aa[i].re*bb[i].im);
res[rev[i]].re:=c.re;
res[rev[i]].im:=-c.im;
end
end;
procedure round(var f: tfur; var res: tlong; s: int);
var
i:int;
cf:int64;
label L1;
begin
cf:=0;
for i:=0 to len-1 do
begin
f[i].re:=f[i].re/len;
cf:=cf+trunc((f[i].re)+0.4);
asm
mov eax,dword ptr cf+4
xor edx,edx
mov ecx,base
div ecx
mov dword ptr cf+4,eax
mov eax,dword ptr cf
div ecx
mov dword ptr cf,eax
mov eax,i
sub eax,s
jl L1
mov ecx,res
mov [ecx+4*eax],edx
L1:
end
end
end;
procedure shift(var aa:tlong;sh:int);
var
i:int;
begin
if sh>0 then
for i:=cl*2 downto 0 do
begin
a[i+sh]:=aa[i];aa[i]:=0
end
else
for i:=0 to cl*2 do
begin
a[i]:=aa[i-sh];aa[i-sh]:=0
end
end;
procedure solve;
var
i, k: int;
s,s1:shortstring;
begin
fillchar(a,sizeof(a),0);
fillchar(b,sizeof(b),0);
fillchar(c,sizeof(c),0);
a[0]:=7071;
cl:=1;
len:=2;len2:=1;
while cl*base10<iter do
begin
if (cl=1024) then
begin
shift(a,-24);
cl:=1000;
end;
while (cl*2>len) or (cl*3>len) and (cl<1000) do
begin
Inc(len2);
len:=len*2;
end;
calc;
copy1(a,aa);
fur(aa);
mult1(aa, aa, cc);
fur(cc);
round(cc,b,0);
c[cl*2-1]:=base div 2;
sub(c, b, b);
c[cl*2-1]:=0;
copy1(b,bb);
fur(bb);
mult1(aa,bb,cc);
fur(cc);
round(cc,b,cl);
shift(a,cl);
add(a,b,a);
cl:=cl*2;
end;
add(a,a,a);
i:=ndigs;
while (a[i]=0) do dec(i);
k:=i;
s:='';s1:='';
write('1.');
while (i>=0) do
begin
str(a[i], s);
if (i<k) then
begin
while (length(s)<base10) do
s:='0'+s;
s1:=s1+s;
if length(s1)>100 then
begin
write(s1);
s1:='';
end
end else
begin
delete(s, 1, 1);
write(s);
end;
dec(i);
end;
writeln(s1);
end;
begin
{$ifndef ONLINE_JUDGE}
assignfile(output, 'output.txt');
rewrite(output);
{$endif}
init;
solve;
end.
-