#include <iostream>
#include <algorithm>
#include <functional>
#include <vector>
#include <cmath>
#include <queue>
#include <string>
using namespace std;
using ld = float;
using vld = vector<ld>;
vld generate(int n)
{
vld result;
for (; n > 0; n--)
result.push_back(ld(1) / n / n);
reverse(result.begin(), result.end());
return result;
}
ld sum_series()
{
ld pi = acos(ld(0)) * 2;
return pi * pi / 6;
}
ld sum_naive(vld v)
{
ld result = 0;
for (auto d : v)
result += d;
return result;
}
ld sum_recursive_range(const vld &v, int l, int r)
{
if (l == r)
return v[r];
int mid = (l + r) / 2;
return sum_recursive_range(v, l, mid) + sum_recursive_range(v, mid + 1, r);
}
ld sum_recursive(vld v)
{
random_shuffle(v.begin(), v.end());
return sum_recursive_range(v, 0, (int)v.size() - 1);
}
ld sum_huffman(vld v)
{
priority_queue<ld, vector<ld>, greater<ld>> q(v.begin(), v.end());
while (q.size() != 1)
{
auto d1 = q.top();
q.pop();
auto d2 = q.top();
q.pop();
q.push(d1 + d2);
}
return q.top();
}
void dump(string prefix, ld x)
{
cout << prefix << ": " << x << " (error " << fabs(x - sum_series()) << ")" << endl;
}
void dump(int n)
{
auto v = generate(n);
cout << "Case #" << n << endl;
dump("Naive direct", sum_naive(v));
reverse(v.begin(), v.end());
dump("Naive reversed", sum_naive(v));
dump("Recursive 1", sum_recursive(v));
dump("Recursive 2", sum_recursive(v));
dump("Recursive 3", sum_recursive(v));
dump("Recursive 4", sum_recursive(v));
dump("Huffman", sum_huffman(v));
}
int main()
{
srand(322);
cout.setf(ios::fixed);
cout.precision(20);
cout << "Series sum: " << sum_series() << endl;
dump(10000000);
return 0;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8YWxnb3JpdGhtPgojaW5jbHVkZSA8ZnVuY3Rpb25hbD4KI2luY2x1ZGUgPHZlY3Rvcj4KI2luY2x1ZGUgPGNtYXRoPgojaW5jbHVkZSA8cXVldWU+CiNpbmNsdWRlIDxzdHJpbmc+CnVzaW5nIG5hbWVzcGFjZSBzdGQ7Cgp1c2luZyBsZCA9IGZsb2F0Owp1c2luZyB2bGQgPSB2ZWN0b3I8bGQ+OwoKdmxkIGdlbmVyYXRlKGludCBuKQp7Cgl2bGQgcmVzdWx0OwoJZm9yICg7IG4gPiAwOyBuLS0pCgkJcmVzdWx0LnB1c2hfYmFjayhsZCgxKSAvIG4gLyBuKTsKCXJldmVyc2UocmVzdWx0LmJlZ2luKCksIHJlc3VsdC5lbmQoKSk7CglyZXR1cm4gcmVzdWx0Owp9CgpsZCBzdW1fc2VyaWVzKCkKewoJbGQgcGkgPSBhY29zKGxkKDApKSAqIDI7CglyZXR1cm4gcGkgKiBwaSAvIDY7Cn0KCmxkIHN1bV9uYWl2ZSh2bGQgdikKewoJbGQgcmVzdWx0ID0gMDsKCWZvciAoYXV0byBkIDogdikKCQlyZXN1bHQgKz0gZDsKCXJldHVybiByZXN1bHQ7Cn0KCmxkIHN1bV9yZWN1cnNpdmVfcmFuZ2UoY29uc3QgdmxkICZ2LCBpbnQgbCwgaW50IHIpCnsKCWlmIChsID09IHIpCgkJcmV0dXJuIHZbcl07CgoJaW50IG1pZCA9IChsICsgcikgLyAyOwoJcmV0dXJuIHN1bV9yZWN1cnNpdmVfcmFuZ2UodiwgbCwgbWlkKSArIHN1bV9yZWN1cnNpdmVfcmFuZ2UodiwgbWlkICsgMSwgcik7Cn0KCmxkIHN1bV9yZWN1cnNpdmUodmxkIHYpCnsKCXJhbmRvbV9zaHVmZmxlKHYuYmVnaW4oKSwgdi5lbmQoKSk7CglyZXR1cm4gc3VtX3JlY3Vyc2l2ZV9yYW5nZSh2LCAwLCAoaW50KXYuc2l6ZSgpIC0gMSk7Cn0KCmxkIHN1bV9odWZmbWFuKHZsZCB2KQp7Cglwcmlvcml0eV9xdWV1ZTxsZCwgdmVjdG9yPGxkPiwgZ3JlYXRlcjxsZD4+IHEodi5iZWdpbigpLCB2LmVuZCgpKTsKCXdoaWxlIChxLnNpemUoKSAhPSAxKQoJewoJCWF1dG8gZDEgPSBxLnRvcCgpOwoJCXEucG9wKCk7CgkJYXV0byBkMiA9IHEudG9wKCk7CgkJcS5wb3AoKTsKCQlxLnB1c2goZDEgKyBkMik7Cgl9CglyZXR1cm4gcS50b3AoKTsKfQoKdm9pZCBkdW1wKHN0cmluZyBwcmVmaXgsIGxkIHgpCnsKCWNvdXQgPDwgcHJlZml4IDw8ICI6ICIgPDwgeCA8PCAiIChlcnJvciAiIDw8IGZhYnMoeCAtIHN1bV9zZXJpZXMoKSkgPDwgIikiIDw8IGVuZGw7Cn0KCnZvaWQgZHVtcChpbnQgbikKewoJYXV0byB2ID0gZ2VuZXJhdGUobik7CgoJY291dCA8PCAiQ2FzZSAjIiA8PCBuIDw8IGVuZGw7CglkdW1wKCJOYWl2ZSBkaXJlY3QiLCBzdW1fbmFpdmUodikpOwoJcmV2ZXJzZSh2LmJlZ2luKCksIHYuZW5kKCkpOwoJZHVtcCgiTmFpdmUgcmV2ZXJzZWQiLCBzdW1fbmFpdmUodikpOwoKCWR1bXAoIlJlY3Vyc2l2ZSAxIiwgc3VtX3JlY3Vyc2l2ZSh2KSk7CglkdW1wKCJSZWN1cnNpdmUgMiIsIHN1bV9yZWN1cnNpdmUodikpOwoJZHVtcCgiUmVjdXJzaXZlIDMiLCBzdW1fcmVjdXJzaXZlKHYpKTsKCWR1bXAoIlJlY3Vyc2l2ZSA0Iiwgc3VtX3JlY3Vyc2l2ZSh2KSk7CgoJZHVtcCgiSHVmZm1hbiIsIHN1bV9odWZmbWFuKHYpKTsKfQoKaW50IG1haW4oKQp7CglzcmFuZCgzMjIpOwoKCWNvdXQuc2V0Zihpb3M6OmZpeGVkKTsKCWNvdXQucHJlY2lzaW9uKDIwKTsKCgljb3V0IDw8ICJTZXJpZXMgc3VtOiAiIDw8IHN1bV9zZXJpZXMoKSA8PCBlbmRsOwoJZHVtcCgxMDAwMDAwMCk7CgoJcmV0dXJuIDA7Cn0KCg==