Codeforces 336B Vasily the Bear and Fly

問題

平面上に半径Rの円が2m個ある。
A1〜Amは中心が座標((2i - 1)R, 0)にあり、
B1〜Bmは中心が座標((2i - 1)R, 2R)にある。


円Aiの中心から円Bjの中心へ、2m個の円の内部または周だけを通って行くときの最短距離をd(i, j)とする。
全ての1≦i, j≦mに対するd(i, j)の平均値を求めよ。

制約条件

m≦10^5

方針

まずd(i, j) =
2*R (i = j)
2*√2 R (|i-j| = 1)
2*(|i-j| - 1 + √2)R (それ以外)
と表せる。


Σd(1, i)はO(m)で計算できる。これをs(1)とおく。
s(2) = Σd(2, i)は、s(1)との差分だけ計算すればO(1)で計算できる。
(変わっているのは、両端の部分だけ)


なので、s(i)は、s(i-1)からO(1)で計算できるので、
Σs(i)は全体でO(m)で計算できる。

ソースコード

double r2 = sqrt(2.0);
int m, r;
double dist(int dx){
	if(dx == 0) return 2 * r;
	if(dx == 1) return (2 + r2) * r;
	return 2 * (dx - 1 + r2) * r;
}
int main(){
	cin >> m >> r;
	double sum = 0, tsum = 0;
	
	rep(i, m) tsum += dist(i);
	rep(i, m){
		sum += tsum;
		tsum -= dist(m - 1 - i);
		tsum += dist(i + 1);
	}
	
	printf("%.9f\n", sum / m / m);
	return 0;
}