文件名是洛谷的比赛编号,不过当时没拿它来测,自己开了个模拟赛。
- 能理解的: 100 + 100 + 100 + 40 = 340
- 实际分数: 100 + 5 + 75 + 25 = 205
T2 T4 都和数据点分治有关,这说明正解不一定都是一个算法走到头。
不想重复正解了,题解有。代码见提交记录。
很简单的签到,可还是没一次写对。30min。
一开始想着分块打表、质因数分解什么的。想了十几分钟后觉得可以尝试枚举底数,感觉到了容斥原理去重但还是没能写出表达式。
后来(剩 1h)想似乎枚举底数也不够,因为 k=2 时枚举量接近 1e9。又想到了类似倍增,比如如果 1e9 平方都在 n 以内,中间的都没必要枚举。
和正解比较,我似乎想到了模糊的做法,可是都不能清晰到实现代码。
正解有两类思路,一个是容斥原理,一个是把非完全平方数放进 std::set<ll>
里去重。前面的没看懂,后面那个看明白了,可是代码断断续续调了两三个小时才调出来。
- 不要试图判断变量溢出,因为 O2 会由于假设代码没有 ub 而把判断溢出的语句删掉。
- ll 求幂不要用 cmath,虽然都是整数但精度难保证。
- 在实际要 cmath 的地方记得用 C++ 的
std::sqrt
等,不然参数类型会对不上。
考场写的是贪心,每步都走最短的。当时就觉得不对但是又造不出反例,我觉得这不是什么直觉,而是一直都对自己的贪心不自信(也没对过)。不明白凸多边形有什么用(现在知道了)。
正解是 dp 很容易看懂,实现之后还是调了很久。边界错了。
考试写的
题解的扫描线建模看不懂,不过