表示敲完多项式乘法&高精度乘法两道FFT模板题后就开始来磕这题了

这题相对而言应该不算模板题 不过神犇们肯定还是一眼看穿

如果原OJ访问速度较慢的话可以考虑戳这里

http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=153505

-------------------------------------------------------------------------------------------------------------

构造什么的 还是太巧妙了

比如对于这样的样例

2

1 2

3 4

可以构造出这样的矩阵(原矩阵在左上角 额外的矩阵在右下角 且两矩阵不相交且中心对称)

a矩阵               b矩阵

1 2 0 0           0 0 0 0

3 4 0 0           0 0 0 0

0 0 0 0           0 0 4 3

0 0 0 0           0 0 2 1

如果变为多项式的话 就是这样

多项式a  1 2 0 0 3 4 0 0 0 0 0 0 0 0 0 0

多项式b  0 0 0 0 0 0 0 0 0 0 4 3 0 0 2 1

当我们把它们乘起来后 会发现贡献到同一项点对的距离是一样的

当n不为2的整数幂的时候 可以像fft模板题一样 通过补零来进行构造

构造出这两个多项式后 我们就可以直接套fft模板 然后对结果多项式的有效的位数都访问一次即可统计出答案

-------------------------------------------------------------------------------------------------------------

不过A掉后还是有一个问题还没弄懂

设多项式a,b的长度为n 那么按照常规的多项式乘法 我们应该把他们后面都补上n个0

因为结果多项式的长度为n×2 (虽然实际有效位数比n还小)

然而我参考的某AC代码 并没有用n×2的长度 而是只用到n的长度让结果 “自然溢出”了 (不是标准说法)

而且貌似n位之后的部分溢出到前面几位了

如果有神犇知道是为什么的话希望能回复下

  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. const int N=<<,M=<<;
  4. const double pi=acos(-);
  5. typedef complex <double> E;
  6. int mp[M][M];
  7. int n,m,L;
  8. int R[N];
  9. long long cnt[N];
  10. E a[N],b[N];
  11. int sum;
  12. double ans;
  13. void fft(E *A,int f)
  14. {
  15. for(int i=;i<n;++i)
  16. if(i<R[i])
  17. swap(A[i],A[R[i]]);
  18. for(int i=;i<n;i<<=)
  19. {
  20. E wn(cos(pi/i),sin(pi/i)*f);
  21. for(int p=i<<,j=;j<n;j+=p)
  22. {
  23. E w(,);
  24. for(int k=;k<i;++k,w*=wn)
  25. {
  26. E x=A[j+k],y=w*A[j+k+i];
  27. A[j+k]=x+y;
  28. A[j+k+i]=x-y;
  29. }
  30. }
  31. }
  32. }
  33. int getdist(int x,int y)
  34. {
  35. return x*x+y*y;
  36. }
  37. int main()
  38. {
  39. scanf("%d",&m);
  40. for(n=;n<m*;n<<=)
  41. ++L;
  42. for(int i=;i<m;++i)
  43. for(int j=;j<m;++j)
  44. {
  45. scanf("%d",&mp[i][j]);
  46. sum+=mp[i][j];
  47. cnt[]-=mp[i][j];
  48. a[i*n+j]=mp[i][j];
  49. b[(n-i-)*n+(n-j-)]=mp[i][j];
  50. }
  51. n=n*n*;
  52. L=L*+;
  53. for(int i=;i<n;++i)
  54. R[i]=(R[i>>]>>)|((i&)<<(L-));
  55. fft(a,);
  56. fft(b,);
  57. for(int i=;i<n;++i)
  58. a[i]*=b[i];
  59. fft(a,-);
  60. int tn=sqrt(n/)/,x,y;
  61. x=tn;
  62. y=tn;
  63. for(int i=*tn*tn-*tn-;i;--i)
  64. {
  65. int tmp1;
  66. if(y>=tn)
  67. tmp1=getdist(x-(tn*-),y-(tn*-));
  68. else
  69. tmp1=getdist(x--(tn*-),tn*--(tn*--y-));
  70. double tmp2=a[x*tn*+y].real()/n;
  71. ans+=sqrt(tmp1)*tmp2;
  72. cnt[tmp1]+=tmp2+0.5;
  73. x+=(y==tn*-);
  74. y=(y==tn*-?:y+);
  75. }
  76. printf("%.10f\n",ans/((long long)sum*(sum-)));
  77. int flag=;
  78. for(int i=;i<m*m*;++i)
  79. if(cnt[i])
  80. {
  81. printf("%d %lld\n",i,cnt[i]/);
  82. if(++flag>=)
  83. break;
  84. }
  85. return ;
  86. }

还是把参考的那个只用了n的长度的多项式的神犇的代码贴一下(如果原作者有意见的话我会删掉的……)

  1. #include<stdio.h>
  2. #include<algorithm>
  3. #include<complex>
  4. #include<vector>
  5. #include<math.h>
  6. #include<map>
  7. using namespace std;
  8. const double PI = 4.0*atan(1.0);
  9. typedef complex<double> Complex;
  10. const Complex I(, );
  11. void fft(int n, double theta, Complex a[]) {
  12. for (int m = n; m >= ; m >>= ) {
  13. int mh = m >> ;
  14. for (int i = ; i < mh; i++) {
  15. Complex w = exp(i*theta*I);
  16. for (int j = i; j < n; j += m) {
  17. int k = j + mh;
  18. Complex x = a[j] - a[k];
  19. a[j] += a[k];
  20. a[k] = w * x;
  21. }
  22. }
  23. theta *= ;
  24. }
  25. int i = ;
  26. for (int j = ; j < n - ; j++) {
  27. for (int k = n >> ; k > (i ^= k); k >>= );
  28. if (j < i) swap(a[i], a[j]);
  29. }
  30. }
  31. int b[][];
  32. Complex p[<<];
  33. Complex q[<<];
  34. int main(){
  35. int a;
  36. scanf("%d",&a);
  37. int cnt=;
  38. for(int i=;i<a;i++){
  39. for(int j=;j<a;j++)scanf("%d",&b[i][j]);
  40. }
  41. int n=;
  42. while(n<a*)n*=;
  43. for(int i=;i<a;i++)for(int j=;j<a;j++){
  44. cnt+=b[i][j];
  45. p[i*n+j]=q[(n--i)*n+(n--j)]=Complex(b[i][j],);
  46. }
  47. fft(n*n,*PI/n/n,p);
  48. fft(n*n,*PI/n/n,q);
  49.  
  50. for(int i=;i<n*n;i++)p[i]=p[i]*q[i];
  51. fft(n*n,-*PI/n/n,p);
  52. for(int i=;i<n*n;i++)p[i]/=n*n;
  53. /*for(int i=0;i<n;i++){
  54. for(int j=0;j<n;j++)printf("%.0f ",p[i*n+j].real());
  55. printf("\n");
  56. }*/
  57. double ret=;
  58. long long sz=;
  59. map<int,long long>m;
  60. for(int i=;i<n*n;i++){
  61. int pi=i/n;
  62. int pj=i%n;
  63. if(pj>=n/)continue;
  64. if(pj==&&pi>=n/)continue;
  65. long long v=(long long)(p[n*n--i].real()+0.5);
  66. if(i==){v-=cnt;v/=;}
  67. if(!v)continue;
  68.  
  69. int I=min(pi,n-pi);
  70. int J=pj;
  71. int t=I*I+J*J;
  72. if(m.count(t)){
  73. m[t]+=v;
  74. }else{
  75. m[t]=v;
  76. }
  77. sz+=v;
  78. ret+=sqrt(t)*v;
  79. }
  80. printf("%.12f\n",ret/sz);
  81. int at=;
  82. for(map<int,long long>::iterator it=m.begin();it!=m.end();it++){
  83. if(at==)break;
  84. at++;
  85. printf("%d %lld\n",(*it).first,(*it).second);
  86. }
  87. }

AIZU 2560 [想法题]的更多相关文章

  1. HDU 4972 Bisharp and Charizard 想法题

    Bisharp and Charizard Time Limit: 1 Sec  Memory Limit: 256 MB Description Dragon is watching NBA. He ...

  2. CodeForces 111B - Petya and Divisors 统计..想法题

    找每个数的约数(暴力就够了...1~x^0.5)....看这约数的倍数最后是哪个数...若距离大于了y..统计++...然后将这个约数的最后倍数赋值为当前位置...好叼的想法题.... Program ...

  3. HDU - 5806 NanoApe Loves Sequence Ⅱ 想法题

    http://acm.hdu.edu.cn/showproblem.php?pid=5806 题意:给你一个n元素序列,求第k大的数大于等于m的子序列的个数. 题解:题目要求很奇怪,很多头绪但写不出, ...

  4. HDU - 5969 最大的位或 想法题

    http://acm.hdu.edu.cn/showproblem.php?pid=5969 (合肥)区域赛签到题...orz 题意:给你l,r,求x|y的max,x,y满足l<=x<=y ...

  5. HDU 4193 Non-negative Partial Sums(想法题,单调队列)

    HDU 4193 题意:给n个数字组成的序列(n <= 10^6).求该序列的循环同构序列中,有多少个序列的随意前i项和均大于或等于0. 思路: 这题看到数据规模认为仅仅能用最多O(nlogn) ...

  6. CodeForces - 156B Suspects 逻辑 线性 想法 题

    题意:有1~N,n(1e5)个嫌疑人,有m个人说真话,每个人的陈述都形如X是凶手,或X不是凶手.现在给出n,m及n个陈述(以+x/-X表示)要求输出每个人说的话是true ,false or notd ...

  7. 2016华中农业大学预赛 E 想法题

    Problem E: Balance Time Limit: 1 Sec  Memory Limit: 128 MBSubmit: 205  Solved: 64[Submit][Status][We ...

  8. codeforces 657C - Bear and Contribution [想法题]

    题目链接: http://codeforces.com/problemset/problem/657/C ----------------------------------------------- ...

  9. POJ 1066 Treasure Hunt [想法题]

    题目链接: http://poj.org/problem?id=1066 --------------------------------------------------------------- ...

随机推荐

  1. JS验证数字

    //1.验证数字 var reg = new RegExp("^[0-9]*$"); //var reg = /^[+]{0,1}(\d+)$|^[+]{0,1}(\d+\.\d+ ...

  2. 厉害了,Google大神每天写多少行代码?

    文章转自开源中国社区,编译自:Quora Quora上有个有趣的问题:Google工程师们每天写多少行代码? Google 的 AdMob 全栈工程师 Raymond Farias 在 Quora 发 ...

  3. [fw]Nvidia Linux Drive Privilege Escalation

    /* Anonymous * * How to use: sudo rm -rf / * * greetz: djrbliss, kad, Ac1dB1tch3z, nVidia! * * Only ...

  4. Winfrom传值 分类: C# 2015-07-22 15:41 1人阅读 评论(0) 收藏

    以前对WinForm窗体显示和窗体间传值了解不是很清楚  最近做了一些WinForm项目,把用到的相关知识整理如下  A.WinForm中窗体显示  显示窗体可以有以下2种方法:  Form.Show ...

  5. 上传.cgi在252板子上跑

    1.windows下写好.c程序 2.进入linux,准备交叉编译 arm-hisiv600-linux-gcc -g -Wall -o xxx.cgi xxx.c(交叉编译工具取决于板子) 3.把. ...

  6. ES6——字符串

    1.多了两个方法       1)startsWith       2)endsWith 2.模板字符串(`..`)—— 方便字符串连接   `反单引号        1)可以直接把表达式塞进去 &a ...

  7. JSONP面试

    jQuery 的 JSONP的原理是动态创建一个 script 标签,利用src 发送请求,获取数据 回调函数的键名叫做  callback 跟ajax没有关系 JSONP:主要是利用 script标 ...

  8. [三下五除二]在Eclipse上的JFinal_Demo

    承接上回在IDEA的JFinal的项目的导入,今次同样是同一个文件,但在Eclipse上运行.在Eclipse上运行官网的JFinal的例子是及其快捷. 打开Eclipse,并进入如下的界面. 点击导 ...

  9. @Profile使用及SpringBoot获取profile值

    版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明.本文链接:https://blog.csdn.net/Fmuma/article/details ...

  10. 基于英伟达Jetson TX1的GPU处理平台

    基于英伟达Jetson TX1 GPU的HDMI图像输入的深度学习套件 [309] 本平台基于英伟达的Jetson TX1视觉计算的全功能开发板,配合本公司研发的HDMI输入图像采集板:Jetson ...