题解:P12083 [Ynoi1998] Marchen
liangbowen · · 题解
最近天天被教练阴阳,有点破防,做点魔怔题增长自信。
显然不弱于 P5046,且强制在线,考虑分块。根据 P5046 的经验,大概是要设计一个严格根号的算法才能过题了。
首先回忆 P5046 的做法:分讨
①⑩:i,j,k 均在左散块(绿绿绿)
枚举
UPD:这样常数太大了,在
②⑨:i,j 在左散块,k 在整块(绿绿红)
枚举
③⑥:i,j 在左散块,k 在右散块(绿绿蓝)
枚举
⑤:i 在左散块,j 在整块,k 在右散块(绿红蓝):
我们没法枚举
④⑧:i 在左散块,j,k 在整块(绿红红)
枚举
考虑预处理
这样总的复杂度保持为
UPD:为了卡常,可以对
⑦:i,j,k 均在整块(红红红)
同 P5046 处理即可:
UPD:这样常数太大了,可以改成
结束。上述所有操作都不带 log,时空复杂度均为
然而这个题代码难度远高于思维难度吧??
首先是卡空间。各种 P5046 的部分应当只用两个 int 的 long long 的
卡时间的话:
- 确保每一部分的做法都比较优,如果某一部分跑得慢就换一个常数小的做法;尽可能将查询里面的复杂度改成
O(1) 的,因为预处理的内存访问比查询的访问快很多。 - cache 问题*太严重了,保证所有
O(n\sqrt n) 数组中固定一维在前面,然后用指针来加速访问,比如 `int FF = F[l]并将所有F[l][i]改成FF[i]`,实测优化巨大。 - 找个快读快写!!这个题输入输出量还是不算小的。
- 我的代码好像有逆天波动,同一份代码交两次差 200ms+,无语。感觉差不多了可以疯狂乱交、换语言交、洗把脸再交。
最后你谷评测机实在有点慢呵,我 QOJ 跑 1.4s 你谷 TLE /fn。不过也无所谓了,最后拼尽全力还是卡过去了,感谢开大实现。