当前位置:   article > 正文

FFT_深入浅出解释fft

深入浅出解释fft
  1. #include<cstdio>
  2. #include<cstring>
  3. #include<cstdlib>
  4. #include<ctime>
  5. #include<cmath>
  6. #include<iostream>
  7. #include<climits>
  8. #include<string>
  9. #include<deque>
  10. #include<queue>
  11. #include<vector>
  12. #include<algorithm>
  13. #include<map>
  14. #include<stack>
  15. #include<set>
  16. using namespace std;
  17. #define LL long long
  18. #define pi (acos(-1.0))
  19. struct complex
  20. {
  21. double r,i;
  22. complex(double _r=0,double _i=0){ r=_r ; i=_i; }
  23. complex operator + (const complex &b) { return complex(r+b.r,i+b.i); }
  24. complex operator - (const complex &b) { return complex(r-b.r,i-b.i); }
  25. complex operator * (const complex &b) { return complex(r*b.r-i*b.i,r*b.i+i*b.r);}
  26. };
  27. void change(complex y[],int len)
  28. {
  29. int i,j,k;
  30. for(i=1,j=len/2; i<len-1; i++)
  31. {
  32. if(i<j) swap(y[i],y[j]);
  33. k=len/2;
  34. while(j>=k)
  35. {
  36. j-=k;
  37. k/=2;
  38. }
  39. if(j<k) j+=k;
  40. }
  41. }
  42. void fft(complex y[],int len,int on)
  43. {
  44. change(y,len);
  45. for(int h=2; h<=len; h<<=1)
  46. {
  47. complex wn(cos(-on*2*pi/h),sin(-on*2*pi/h));
  48. for(int j=0; j<len;j+=h)
  49. {
  50. complex w(1,0);
  51. for(int k=j;k<j+h/2;k++)
  52. {
  53. complex u=y[k];
  54. complex t=w*y[k+h/2];
  55. y[k]= u+t;
  56. y[k+h/2]=u-t;
  57. w=w*wn;
  58. }
  59. }
  60. }
  61. if(on==-1)
  62. for(int i=0;i<len;i++)
  63. y[i].r/=len;
  64. }
  65. const int maxn=810010;
  66. complex x1[maxn];
  67. LL num[maxn];
  68. int a[maxn];
  69. void dofft(LL len1)
  70. {
  71. int len=1;
  72. while(len < 2*len1) len<<=1;
  73. for(int i=0;i<len1;i++) x1[i]=complex(num[i],0);
  74. for(int i=len1;i<len;i++) x1[i]=complex(0,0);
  75. fft(x1,len,1);
  76. for(int i=0;i<len;i++) x1[i]=x1[i]*x1[i];
  77. fft(x1,len,-1);
  78. for(int i=0;i<len;i++) num[i]=(LL)(x1[i].r+0.5);
  79. }
  80. int main()
  81. {
  82. #ifndef ONLINE_JUDGE
  83. freopen("in.txt","r",stdin);
  84. freopen("out.txt","w",stdout);
  85. #endif
  86. int t; scanf("%d",&t);
  87. int n;
  88. while(t--)
  89. {
  90. memset(num,0,sizeof(num));
  91. scanf("%d",&n);
  92. for(int i=0;i<n;i++)
  93. {
  94. scanf("%d",&a[i]);
  95. num[a[i]]++;
  96. }
  97. sort(a,a+n);
  98. dofft(a[n-1]+1);
  99. LL len=2*a[n-1];
  100. for(int i=0;i<n;i++) num[a[i]+a[i]]--;
  101. for(int i=1;i<=len;i++) num[i]/=2;
  102. for(int i=1;i<=len;i++) num[i]+=num[i-1];
  103. double ans=0.0;
  104. for(int i=0;i<n;i++)
  105. {
  106. ans+=num[len]-num[a[i]];
  107. ans-=(n-i-1)*(double)i;
  108. ans-=(double)(n-1);
  109. ans-=(n-i-1)*(double)(n-i-2)/2.0;
  110. }
  111. double all=(double)n*(n-1)*(n-2)/6.0;
  112. printf("%.7f\n",ans/all);
  113. }
  114. return 0;
  115. }


声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/代码探险家/article/detail/883060
推荐阅读
相关标签
  

闽ICP备14008679号