voidgen_input(constint n, constint seed){ double x = (double)(seed); unsignedint iseed = seed; for (int i = 0; i < n; ++i) { iseed = iseed * 1664525 + 1013904223; x = (std::sin(iseed % 4096) + 1) / 2; a[i] = std::fabs(x * (iseed >> (iseed % 30))) + 1e-9; } }
intmain(){ std::cin >> n >> seed; gen_input(n, seed);
// 你需要优化这行代码 std::sort(a, a + n);
double ans = 0; for (int i = 0; i < n; i++) { ans += a[i] * (i % 9); } std::cout.precision(10); std::cout << std::fixed << ans << std::endl; return0; }
思路
赛场上看到这道题目一脸懵,到底是哪个出题人出的题啊。
赛后发现这道题其实考察的是浮点数。浮点数由于其特殊的存储特性,比较的常数是特别大的,但是将 double 类型转换为 long long 类型是不影响比较的,所以只需要添加一行代码:
但是这道题要求是变成一条链,所以其答案一定和深度有关,不难发现将这棵树变为一条链的最小操作次数为 n−maxudep(u)。所以不应该以重链剖分的思路解这道题,而是长链剖分。其他的思路就和上面一样了。就是不断的把 u 的长链剖分意义下的重儿子接到任意一个轻儿子上 (选择的轻儿子变为下一次的重儿子),不断重复这个操作,直到 u 不存在轻儿子。