题意:

有一个\(N \times N\)的方阵,第\(x\)行第\(y\)列有\(C_{x,y}\)个点\((0 \leq C_{x,y} \leq 9)\)。

任选两个不同的点,求两点欧几里德距离的均值(或期望)。

然后按距离从小到大输出该距离的平方\(d_i\)和对应的点对数目\(c_i\)。

分析:

首先要化二维为一维,一般来讲给点\((x,y)\)编号\(x \times N+y(0\leq x, y < N)\)。

这里为了区分行和列从而方便计算距离,按照\(x \times 2N + y\)的方式给点编号。

这样对于两个点\((x_1,y_1)\)和\((x_2, y_2)\),对应编号分别为\(id_1 = x_1 \times 2N + y_1\)和\(id_2 = x_2 \times 2N + y_2(id_1 < id_2)\)。

两点之间的行距\(dx=\left \lceil \frac{id_1 - id_2 + N}{2} \right \rceil\)

两点之间的列距\(dy=\left | id_1 - id_2 -dx\times 2N \right |\)

然后用\(FFT\)计算两个多项式:

\[P(x)=\sum C_{i,j}x^{id_{i,j}}
\]

\[Q(x)=\sum C_{i,j}x^{-id_{i,j}}
\]

的乘积。

距离为\(0\)的点对注意去重或者单独计算。

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <complex>
using namespace std; const double PI = acos(-1.0);
typedef long long LL;
typedef complex<double> Complex; void FFT(Complex* P, int n, int op) {
for(int i = 1, j = 0; i < n - 1; i++) {
for(int s = n; j ^= s >>= 1, ~j&s; );
if(i < j) swap(P[i], P[j]);
}
int log = 0;
while((1 << log) < n) log++;
for(int s = 0; s < log; s++) {
int m = 1 << s;
int m2 = m << 1;
Complex wm(cos(PI / m), sin(PI / m) * op);
for(int i = 0; i < n; i += m2) {
Complex w(1, 0);
for(int j = 0; j < m; j++, w *= wm) {
Complex u = P[i + j];
Complex t = P[i + j + m] * w;
P[i + j] = u + t;
P[i + j + m] = u - t;
}
}
}
if(op == -1) for(int i = 0; i < n; i++) P[i].real(P[i].real() / n);
} Complex P[2][1 << 22]; int n; LL cnt[2100000]; double dist(double x, double y) {
return sqrt(x * x + y * y);
} int main()
{
scanf("%d", &n);
int sum = 0;
int offset = (n - 1) * (n * 2 + 1);
for(int i = 0; i < n; i++) {
for(int j = 0; j < n; j++) {
int x; scanf("%d", &x);
sum += x;
cnt[0] += (x - 1) * x / 2;
int id = i * 2 * n + j;
P[0][id] = x;
P[1][offset-id] = x;
}
} int s = 1;
while(s < offset * 2 + 1) s <<= 1;
FFT(P[0], s, 1); FFT(P[1], s, 1);
for(int i = 0; i < s; i++) P[0][i] *= P[1][i];
FFT(P[0], s, -1); double ans = 0;
for(int i = 1; i <= offset; i++) {
LL t = (LL)(P[0][offset + i].real() + 0.5);
if(!t) continue;
int dx = ((i / n) + 1) >> 1;
int dy = abs(i - dx * n * 2);
ans += dist(dx, dy) * t;
cnt[dx*dx+dy*dy] += t;
} ans /= (double)sum * (sum - 1) / 2;
printf("%.10f\n", ans); int num = 0; int top = (n - 1) * (n - 1) * 2;
for(int i = 0; i <= top && num < 10000; i++) if(cnt[i]) {
printf("%d %lld\n", i, cnt[i]);
num++;
} return 0;
}

Aizu 2560 Point Distance FFT的更多相关文章

  1. AIZU 2560 [想法题]

    表示敲完多项式乘法&高精度乘法两道FFT模板题后就开始来磕这题了 这题相对而言应该不算模板题 不过神犇们肯定还是一眼看穿 如果原OJ访问速度较慢的话可以考虑戳这里 http://acm.hus ...

  2. CodeChef - PRIMEDST Prime Distance On Tree 树分治 + FFT

    Prime Distance On Tree Problem description. You are given a tree. If we select 2 distinct nodes unif ...

  3. codechef Prime Distance On Tree(树分治+FFT)

    题目链接:http://www.codechef.com/problems/PRIMEDST/ 题意:给出一棵树,边长度都是1.每次任意取出两个点(u,v),他们之间的长度为素数的概率为多大? 树分治 ...

  4. prime distance on a tree(点分治+fft)

    最裸的点分治+fft,调了好久,太菜了.... #include<iostream> #include<cstring> #include<cstdio> #inc ...

  5. [题解] Atcoder ABC 225 H Social Distance 2 生成函数,分治FFT

    题目 首先还没有安排座位的\(m-k\)个人之间是有顺序的,所以先把答案乘上\((m-k)!\),就可以把这些人看作不可区分的. 已经确定的k个人把所有座位分成了k+1段.对于第i段,如果我们能求出这 ...

  6. LA6886 Golf Bot(FFT)

    题目 Source https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page= ...

  7. Codeforces 528D Fuzzy Search(FFT)

    题目 Source http://codeforces.com/problemset/problem/528/D Description Leonid works for a small and pr ...

  8. LA4671 K-neighbor substrings(FFT + 字符串Hash)

    题目 Source http://acm.hust.edu.cn/vjudge/problem/19225 Description The Hamming distance between two s ...

  9. hdu 5885 FFT

    XM Reserves Time Limit: 10000/10000 MS (Java/Others)    Memory Limit: 102400/102400 K (Java/Others)T ...

随机推荐

  1. C# 执行可执行文件

    可以用C#脚本执行可执行文件,一般可以用C# IO流写出.bat脚本,然后顺带执行脚本,然后滑稽.三连... Process proc = null; try { proc = new Process ...

  2. 微信公众平台网页开发实战--3.利用JSSDK在网页中获取地理位置(HTML5+jQuery)

    复制一份JSSDK环境,创建一份index.html文件,结构如图7.1所示. 图7.1  7.1节文件结构 在location.js中,封装“getLocation”接口,如下: 01 wxJSSD ...

  3. 【软件使用心得】Quartus和ISE调用Synplify进行综合的问题

    分别尝试采用Quartus和ISE调用第三方综合软件Synplify进行综合. [软件版本] Quartus II 13.0 (SP).ISE 14.4 .Synplify 201303. [问题描述 ...

  4. GBase数据库存储过程——批量查询多个数据表的磁盘占用情况

    --清理历史表,可选 DROP TABLE IF EXISTS `dap_model`.`data_statics`; CREATE TABLE `dba`.`data_statics` ( `TAB ...

  5. 慎用python的pop和remove方法

    申明:转载请注明出处!!! Python关于删除list中的某个元素,一般有两种方法,pop()和remove(). 如果删除单个元素,使用基本没有什么问题,具体如下. 1.pop()方法,传递的是待 ...

  6. iptables (1) 原理

    网上看到这个配置讲解得还比较易懂,就转过来了,大家一起看下,希望对您工作能有所帮助. iptables简介 netfilter/iptables(简称为iptables)组成Linux平台下的包过滤防 ...

  7. Jmeter模拟http请求

    一.获取用户信息(GET请求):http://hostname/getuser?userid=1 1.打开jmeter,创建一个线程组,再添加一个http请求Sampler 2.设置域名.路径.请求方 ...

  8. git 修改commit 的注释

    git 修改commit 的注释 一:最新的一次提交 当你不小心,写错了提交的注视/信息,该如何处理呢.理论上,SCM是不应该修改历史的信息的,提交的注释也是.    不过在git中,其commit提 ...

  9. 使TextBox的内容换行

    首先你把TextBox控件的MultiLine属性设置为True,然后把TextBox控件的Text属性根据程序需要,在需要换行的地方加入\r\n这样就可实现换行了

  10. css中如何把鼠标变成手

    css中鼠标放上去变成手型怎么设置:其实就是一个属性的问题, css的cursor属性 cursor:pointer; 其实这个属性我也记了很多,到现在都容易拼写错误,不过好在编辑器有提示. defa ...