#include <iostream>
#include <algorithm>
#include <functional>
#include <vector>
#include <cmath>
#include <queue>
#include <string>
using namespace std;
using ld = double;
using vld = vector<ld>;
using vi = vector<int>;
ld base()
{
return atan(ld(2.718281828));
}
pair<vld, ld> generate(int n)
{
vi test;
for (; n > 0; n--)
test.push_back(rand() % 10000);
vld result;
int64_t sum = 0;
for (auto d : test)
{
result.push_back(base() * d);
sum += d;
}
return { result, sum * base() };
}
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, ld sum)
{
cout << prefix << ": " << x << " (error " << fabs(x - sum) << ")" << endl;
}
void dump(int n)
{
auto input = generate(n);
auto v = input.first;
sort(v.begin(), v.end());
cout << "Case n = " << n << endl;
cout << "Series sum: " << input.second << endl;
dump("Naive direct", sum_naive(v), input.second);
reverse(v.begin(), v.end());
dump("Naive reversed", sum_naive(v), input.second);
dump("Recursive 1", sum_recursive(v), input.second);
dump("Recursive 2", sum_recursive(v), input.second);
dump("Recursive 3", sum_recursive(v), input.second);
dump("Recursive 4", sum_recursive(v), input.second);
dump("Huffman", sum_huffman(v), input.second);
}
int main()
{
srand(322);
cout.setf(ios::fixed);
cout.precision(20);
dump(100000);
dump(100000);
dump(1000000);
dump(1000000);
return 0;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8YWxnb3JpdGhtPgojaW5jbHVkZSA8ZnVuY3Rpb25hbD4KI2luY2x1ZGUgPHZlY3Rvcj4KI2luY2x1ZGUgPGNtYXRoPgojaW5jbHVkZSA8cXVldWU+CiNpbmNsdWRlIDxzdHJpbmc+CnVzaW5nIG5hbWVzcGFjZSBzdGQ7Cgp1c2luZyBsZCA9IGRvdWJsZTsKdXNpbmcgdmxkID0gdmVjdG9yPGxkPjsKdXNpbmcgdmkgPSB2ZWN0b3I8aW50PjsKCmxkIGJhc2UoKQp7CglyZXR1cm4gYXRhbihsZCgyLjcxODI4MTgyOCkpOwp9CgpwYWlyPHZsZCwgbGQ+IGdlbmVyYXRlKGludCBuKQp7Cgl2aSB0ZXN0OwoJZm9yICg7IG4gPiAwOyBuLS0pCgkJdGVzdC5wdXNoX2JhY2socmFuZCgpICUgMTAwMDApOwoKCXZsZCByZXN1bHQ7CglpbnQ2NF90IHN1bSA9IDA7Cglmb3IgKGF1dG8gZCA6IHRlc3QpCgl7CgkJcmVzdWx0LnB1c2hfYmFjayhiYXNlKCkgKiBkKTsKCQlzdW0gKz0gZDsKCX0KCglyZXR1cm4geyByZXN1bHQsIHN1bSAqIGJhc2UoKSB9Owp9CgpsZCBzdW1fbmFpdmUodmxkIHYpCnsKCWxkIHJlc3VsdCA9IDA7Cglmb3IgKGF1dG8gZCA6IHYpCgkJcmVzdWx0ICs9IGQ7CglyZXR1cm4gcmVzdWx0Owp9CgpsZCBzdW1fcmVjdXJzaXZlX3JhbmdlKGNvbnN0IHZsZCAmdiwgaW50IGwsIGludCByKQp7CglpZiAobCA9PSByKQoJCXJldHVybiB2W3JdOwoKCWludCBtaWQgPSAobCArIHIpIC8gMjsKCXJldHVybiBzdW1fcmVjdXJzaXZlX3JhbmdlKHYsIGwsIG1pZCkgKyBzdW1fcmVjdXJzaXZlX3JhbmdlKHYsIG1pZCArIDEsIHIpOwp9CgpsZCBzdW1fcmVjdXJzaXZlKHZsZCB2KQp7CglyYW5kb21fc2h1ZmZsZSh2LmJlZ2luKCksIHYuZW5kKCkpOwoJcmV0dXJuIHN1bV9yZWN1cnNpdmVfcmFuZ2UodiwgMCwgKGludCl2LnNpemUoKSAtIDEpOwp9CgpsZCBzdW1faHVmZm1hbih2bGQgdikKewoJcHJpb3JpdHlfcXVldWU8bGQsIHZlY3RvcjxsZD4sIGdyZWF0ZXI8bGQ+PiBxKHYuYmVnaW4oKSwgdi5lbmQoKSk7Cgl3aGlsZSAocS5zaXplKCkgIT0gMSkKCXsKCQlhdXRvIGQxID0gcS50b3AoKTsKCQlxLnBvcCgpOwoJCWF1dG8gZDIgPSBxLnRvcCgpOwoJCXEucG9wKCk7CgkJcS5wdXNoKGQxICsgZDIpOwoJfQoJcmV0dXJuIHEudG9wKCk7Cn0KCnZvaWQgZHVtcChzdHJpbmcgcHJlZml4LCBsZCB4LCBsZCBzdW0pCnsKCWNvdXQgPDwgcHJlZml4IDw8ICI6ICIgPDwgeCA8PCAiIChlcnJvciAiIDw8IGZhYnMoeCAtIHN1bSkgPDwgIikiIDw8IGVuZGw7Cn0KCnZvaWQgZHVtcChpbnQgbikKewoJYXV0byBpbnB1dCA9IGdlbmVyYXRlKG4pOwoJYXV0byB2ID0gaW5wdXQuZmlyc3Q7CgoJc29ydCh2LmJlZ2luKCksIHYuZW5kKCkpOwoKCWNvdXQgPDwgIkNhc2UgbiA9ICIgPDwgbiA8PCBlbmRsOwoJY291dCA8PCAiU2VyaWVzIHN1bTogIiA8PCBpbnB1dC5zZWNvbmQgPDwgZW5kbDsKCglkdW1wKCJOYWl2ZSBkaXJlY3QiLCBzdW1fbmFpdmUodiksIGlucHV0LnNlY29uZCk7CglyZXZlcnNlKHYuYmVnaW4oKSwgdi5lbmQoKSk7CglkdW1wKCJOYWl2ZSByZXZlcnNlZCIsIHN1bV9uYWl2ZSh2KSwgaW5wdXQuc2Vjb25kKTsKCglkdW1wKCJSZWN1cnNpdmUgMSIsIHN1bV9yZWN1cnNpdmUodiksIGlucHV0LnNlY29uZCk7CglkdW1wKCJSZWN1cnNpdmUgMiIsIHN1bV9yZWN1cnNpdmUodiksIGlucHV0LnNlY29uZCk7CglkdW1wKCJSZWN1cnNpdmUgMyIsIHN1bV9yZWN1cnNpdmUodiksIGlucHV0LnNlY29uZCk7CglkdW1wKCJSZWN1cnNpdmUgNCIsIHN1bV9yZWN1cnNpdmUodiksIGlucHV0LnNlY29uZCk7CgoJZHVtcCgiSHVmZm1hbiIsIHN1bV9odWZmbWFuKHYpLCBpbnB1dC5zZWNvbmQpOwp9CgppbnQgbWFpbigpCnsKCXNyYW5kKDMyMik7CgoJY291dC5zZXRmKGlvczo6Zml4ZWQpOwoJY291dC5wcmVjaXNpb24oMjApOwoKCWR1bXAoMTAwMDAwKTsKCWR1bXAoMTAwMDAwKTsKCWR1bXAoMTAwMDAwMCk7CglkdW1wKDEwMDAwMDApOwoKCXJldHVybiAwOwp9Cgo=