[USACO16OPEN][区间DP] 262144 P
题面
和通常套路不太一样,这题 \(N \le 262144\),不可以通过枚举区间的方程转移出来。
实际上,我们通过合并最大可以得出 \(58\),这个 \(58\) 实际就是 \(18 + 40\),\(40\) 是显然的,但是 \(18\) 呢?
我们考虑合并的过程,实际与倍增过程类似,最多我们会合并 \(\log n\) 次,再看看数据范围:\(2^{18} = 262144\)!
于是我们就有了代码中的方程。
代码:
# include <iostream>
# include <cstdio>
# define MAXN 60
# define MAXM 270000
int f[MAXM][MAXN]; // f[i][j] 以 i 为左端点,合并出 j 的答案
int a[MAXM];
int main(){
int n, ans = 0;
scanf("%d", &n);
for(int i = 1; i <= n; i++){
scanf("%d", &a[i]);
f[i][a[i]] = i+1;
}
for(int j = 2; j <= 58; j++){
for(int i = 1; i <= n; i++){
if(!f[i][j]){
f[i][j] = f[f[i][j-1]][j-1];
}
if(f[i][j]){
ans = std::max(ans, j);
}
}
}
printf("%d", ans);
return 0;
}