Назад к лучшим решениям Status: AC, problem ZSQRT2, contest ZEL07. By levlam (Levin Aleksey), 2007-02-15 10:23:55.
  1. #include <stdio.h>
  2. #include <math.h>
  3. #include <memory.h>
  4. #define base 10000
  5. #define N 2000010
  6. #define MaxN N/4
  7. #define S2 0.7071067811865475244008443621
  8. #define doFHT(x, y)\
  9. x=new double[newl];\
  10. memset(x, 0, newl<<3);\
  11. for (i=0; i<l; i++) x[i]=y[i];\
  12. FHT(x, newl);
  13. #define FHTB(i1,i2,C,S)\
  14. t1=L[i1]-R[i1], t2=L[i2]-R[i2];\
  15. L[i1]+=R[i1];\
  16. L[i2]+=R[i2];\
  17. R[i1]=t1*C+t2*S;\
  18. R[i2]=t1*S-t2*C;
  19.  
  20. int a[4*MaxN+10], b[2*MaxN+10], c[2*MaxN+10], d[4*MaxN+10], z[4*MaxN+10];
  21. double st[80];
  22.  
  23. void Sum(int *x, int *y, int *z, int l1, int l2)
  24. {
  25. int *p=y, *p1=y+l1, *p2=z, *p3=x, *p4=z+l2, um=0;
  26. for (; p<p1 && p2<p4; p++, p2++, p3++)
  27. {
  28. *p3+=um+*p+*p2;
  29. for (um=0; *p3>=base; um++) *p3-=base;
  30. }
  31. while (p<p1)
  32. {
  33. *p3+=um+*p;
  34. um=0;
  35. if (*p3>=base) um=1, *p3-=base;
  36. p++, p3++;
  37. }
  38. while (p2<p4)
  39. {
  40. *p3+=um+*p2;
  41. um=0;
  42. if (*p3>=base) um=1, *p3-=base;
  43. p2++, p3++;
  44. }
  45. while (um>0)
  46. {
  47. *p3+=um;
  48. um=0;
  49. if (*p3>=base) um=1, *p3-=base;
  50. p3++;
  51. }
  52. }
  53.  
  54. void Umen(int *x, int *y, int l)
  55. {
  56. int *p=x, *p1=y, *p2=x+l, t;
  57. for (; p<=p2; p1++)
  58. {
  59. t=*p-*p1;
  60. if (t>=0) *p++=t;
  61. else
  62. *p=base+t, (*(++p))--;
  63. }
  64. while ((*p)<0)
  65. *p+=base, (*(++p))--;
  66. }
  67.  
  68. void FHT(double *a, int l)
  69. {
  70. if (l==4)
  71. {
  72. double d0=a[0], d1=a[1], d2=a[2], d3=a[3];
  73. a[0]=d0+d1+d2+d3;
  74. a[1]=d0-d1+d2-d3;
  75. a[2]=d0+d1-d2-d3;
  76. a[3]=d0-d1-d2+d3;
  77. return;
  78. }
  79. l>>=1;
  80. int x, l2=l>>1, l4=l>>2;
  81. for (x=-1; l; x++) l>>=1;
  82. l=l2<<1;
  83. double *L=a, *R=a+l, t1, t2, t, S0=st[x], C0=st[x+1], S, C;
  84. C0=-2.0*C0*C0;
  85. S=S0, C=1.0+C0;
  86. t1=L[0], t2=R[0];
  87. L[0]=t1+t2, R[0]=t1-t2;
  88. t1=L[l2], t2=R[l2];
  89. L[l2]=t1+t2, R[l2]=t1-t2;
  90. for (x=1;x<l4;x++)
  91. {
  92. FHTB(x,l-x,C,S);
  93. FHTB(l2-x,l2+x,S,C);
  94. t=C;
  95. C=C*C0-S*S0+C;
  96. S=S*C0+t*S0+S;
  97. }
  98. FHTB(l4,l-l4,S2,S2);
  99. FHT(L,l);
  100. FHT(R,l);
  101. }
  102.  
  103. void FHTReOrder(double *a, int l)
  104. {
  105. double t;
  106. int i, tt, r=0;
  107. if (l<=2) return;
  108. for (i=1; i<l; i++)
  109. {
  110. tt=l;
  111. do
  112. {
  113. l>>=1;
  114. r^=l;
  115. }while ((r&l)==0);
  116. l=tt;
  117. if (r>i) t=a[i], a[i]=a[r], a[r]=t;
  118. }
  119. }
  120.  
  121. void Umn(int *x, int *y, int *z, int l)
  122. {
  123. int newl=8, i, j, k;
  124. double *a, *b, ad, sd, t, um=0;
  125. while (newl<l+l) newl<<=1;
  126. doFHT(a,y);
  127. doFHT(b,z);
  128. a[0]*=b[0]+b[0];
  129. a[1]*=b[1]+b[1];
  130. for (k=2; k<newl; k*=2)
  131. for (i=k, j=k+k-1; j>=k; i+=2, j-=2)
  132. {
  133. ad=a[i]+a[j];
  134. sd=a[i]-a[j];
  135. a[i]=b[i]*ad+b[j]*sd;
  136. a[j]=b[j]*ad-b[i]*sd;
  137. }
  138. FHTReOrder(a,newl);
  139. FHT(a,newl);
  140. FHTReOrder(a,newl);
  141. for (j=0; j<l+l; j++)
  142. {
  143. t=floor(a[j]*0.5/newl+um+x[j]+0.5);
  144. um=floor(t/base);
  145. x[j]=t-um*base;
  146. }
  147. while (um!=0)
  148. {
  149. t=floor(um+x[j]+0.5);
  150. um=floor(t/base);
  151. x[j++]=t-um*base;
  152. }
  153. delete[] a;
  154. delete[] b;
  155. return;
  156. }
  157.  
  158. int main(void)
  159. {
  160. int i, k, l=1, deg, dd, t;
  161. long long z0;
  162. a[0]=3;
  163. b[0]=2;
  164. for (i=0, k=1; k<=(N<<3); k*=2)
  165. st[i++]=sin(3.1415926535897932384626433832/k);
  166. while (2*l<MaxN)
  167. {
  168. Umn(d,a,b,l);
  169. Sum(d,d,NULL,(l<<1)+2,0);
  170. Umn(c,b,b,l);
  171. Sum(c,c,NULL,(l<<1)+2,0);
  172. Umn(c,a,a,l);
  173. l=(l<<1)+2;
  174. while (c[l-1]==0 && d[l-1]==0) l--;
  175. memcpy(a, c, l<<2);
  176. memcpy(b, d, l<<2);
  177. memset(c, 0, l<<2);
  178. memset(d, 0, l<<2);
  179. }
  180. for (deg=1, dd=0; deg<MaxN; deg<<=1, dd++) ;
  181. deg+=3;
  182. for (i=deg-1; i-deg+l>=0 ; i--)
  183. b[i]=b[i-deg+l];
  184. memset(b, 0, (deg-l)<<2);
  185. while (b[deg-1]==0) deg--;
  186. z0=1.0*base*base*base*base*base/((1.0*b[deg-1]*base+b[deg-2])*base+b[deg-3]);
  187. z[2]=(z0/base)/base;
  188. z[1]=(z0/base)%base;
  189. z[0]=z0%base;
  190. for (k=0, t=1; k<dd; k++)
  191. {
  192. Umn(c,z,z,t+2);
  193. if (k<dd-1)
  194. Umn(d,c,b+(deg-(2*t+3)),2*t+4);
  195. else
  196. Umn(d+2*(2*t+2-MaxN),c+(2*t+2-MaxN),b+(deg-MaxN-1), MaxN+2);
  197. Sum(z+(t+t+t+4),z,z,t+2,t+2);
  198. memset(z, 0, (t+2)<<2);
  199. Umen(z, d, (t<<2)+7);
  200. memcpy(z, z+(t+t+4), (t+t+2)<<2);
  201. memset(z+(t+t+2), 0, (t+t+5)<<2);
  202. c[0]=1;
  203. Sum(z,c,NULL,1,0);
  204. memset(c, 0, (t+t+4)<<2);
  205. memset(d, 0, (4*t+6)<<2);
  206. t<<=1;
  207. }
  208. Umn(c, a, z+(t+2-MaxN), MaxN+1);
  209. deg=MaxN+MaxN+2;
  210. while (c[deg]==0) deg--;
  211. if (c[deg]>=1000) printf("1.414");
  212. else if (c[deg]>=100) printf("1.41");
  213. else if (c[deg]>=10) printf("1.4");
  214. else printf("1.");
  215. for (i=1; i<MaxN-2; i++)
  216. printf("%04d", c[deg-i]);
  217. printf("76");
  218. return 0;
  219. }