LOJ #2802. 「CCC 2018」平衡树(整除分块 + dp)

题面

LOJ #2802. 「CCC 2018」平衡树

题面有点难看。。。请认真阅读理解题意。

转化后就是,给你一个数 N ,每次选择一个 k[2,N]N 变成 Nk ,到 1 停止。

求一共有多少不同的操作序列,也就是操作次数不一样或者某次操作的 k 不相同。

题解

首先考虑 dp ,令 fi 为以 i 为开头的不同操作序列数。

显然有一个转移:

fi=k=2ifik

边界为 f1=1

显然这个式子能用整除分块来进行优化,就是对于 ik 相同一起处理,很容易发现这些 fik 也是相同的。

这是因为

nxy=nxy

证明是很显然的。

所以有用的 f 总共只有 N 个。

那么我们记忆化搜索即可,然后用一些对于这个利用整除分块的常用标号的方式。

也就是 x<NxxNNx

不断递归下去就行了,深度是 logN 的。

然后复杂度?不会证。这是个整除分块套整除分块。。

著名 OI 选手 zhou888 口胡证明是 O(N34) 的。

总结

要相信分块套起来的复杂度,然后记忆化的时候最好手写哈希,或者用一些特殊性质,常数能小很多。

代码

#include <bits/stdc++.h> #define For(i, l, r) for(register int i = (l), i##end = (int)(r); i <= i##end; ++i) #define Fordown(i, r, l) for(register int i = (r), i##end = (int)(l); i >= i##end; --i) #define Set(a, v) memset(a, v, sizeof(a)) #define Cpy(a, b) memcpy(a, b, sizeof(a)) #define debug(x) cout << #x << ": " << x << endl #define DEBUG(...) fprintf(stderr, __VA_ARGS__) using namespace std; inline bool chkmin(int &a, int b) {return b < a ? a = b, 1 : 0;} inline bool chkmax(int &a, int b) {return b > a ? a = b, 1 : 0;} inline int read() { int x = 0, fh = 1; char ch = getchar(); for (; !isdigit(ch); ch = getchar()) if (ch == '-') fh = -1; for (; isdigit(ch); ch = getchar()) x = (x << 1) + (x << 3) + (ch ^ 48); return x * fh; } void File() { #ifdef zjp_shadow freopen ("2802.in", "r", stdin); freopen ("2802.out", "w", stdout); #endif } typedef long long ll; const int Maxn = 1e6 + 1e3; int n; ll Ans1[Maxn], Ans2[Maxn]; inline void Insert(int pos, ll uv) { if (pos < Maxn) Ans1[pos] = uv; else Ans2[n / pos] = uv; } inline ll Find(int pos) { return pos < Maxn ? Ans1[pos] : Ans2[n / pos]; } ll Dp(int val) { if (val == 1) return 1; ll res = Find(val); if (res) return res; for (register int i = 2, Nexti; i <= val; i = Nexti + 1) Nexti = val / (val / i), res += Dp(val / i) * (Nexti - i + 1); Insert(val, res); return res; } int main () { File(); n = read(); printf ("%lld\n", Dp(n)); return 0; }

__EOF__

本文作者zjp_shadow
本文链接https://www.cnblogs.com/zjp-shadow/p/9490432.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   zjp_shadow  阅读(200)  评论(0编辑  收藏  举报
编辑推荐:
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
点击右上角即可分享
微信分享提示