P3147 [USACO16OPEN] 262144 P
题目链接
看到这道题,不难想到可能和区间 dp 有关,那么便可设 \(f_{i,j}\) 表示 \(i\sim j\) 区间的最高分数。但是 N 太大了,分数又很小,那么就把这两个东西换过来,即设 \(f_{l,i}=r\) 表示 \(l\sim r-1\) 区间的分数为 \(i\)(可以证明出 \(r\) 是唯一的),然后考虑状态转移。
\[f_{l,i}=f_{f_{l,i-1},i-1}
\]
#include<bits/stdc++.h>
#define LL long long
//#define int LL
#define per(i, a, b) for (int i = a, END##i = b; i >= END##i; i--)
#define rep(i, a, b) for (int i = a, END##i = b; i <= END##i; i++)
#define repn(x) rep(x, 1, n)
#define repm(x) rep(x, 1, m)
#define pb push_back
#define e(x) for(int i = h[x], v = to[i]; i; i = nxt[i], v = to[i])
#define E(x) for(auto y : p[x])
#define PII pair<int, int>
#define i64 unsigned long long
#define YY puts("Yes"), exit(0)
#define NN puts("No"), exit(0)
using namespace std;
const int Mod = 1e9 + 7;
const int Inf = 0x3f3f3f3f;
const LL InfLL = 0x3f3f3f3f3f3f3f3f;
inline LL read() {LL s = 0, fu = 1; char ch = getchar(); while (ch < '0' || ch > '9') ch == '-' ? fu = -1 : 0, ch = getchar(); while (ch >= '0' && ch <= '9') s = (s << 1) + (s << 3) + (ch ^ 48), ch = getchar(); return s * fu;}
inline void add(int &a, int b) {((a += b) >= Mod) and (a -= Mod);}
inline int Add(int a, int b) {return add(a, b), a;}
inline int mul(int a, int b) {return 1LL * a * b % Mod;}
inline void Mul(int &a, int b) {a = mul(a, b);}
inline int qpow(int a, LL b){if(!b) return 1; int c = qpow(a, b >> 1LL); Mul(c, c); if(b & 1) Mul(c, a); return c;}
inline int INV(int x) {return qpow(x, Mod - 2);}
const int N = 3e5 + 10, M = 100;
int f[N][M], n, ans;
inline void Main() {
n = read();
repn(i) {
int x = read();
f[i][x] = i + 1;
}
rep(i, 1, 58) { // 40 + log2(262144)
repn(l) {
if (!f[l][i]) f[l][i] = f[f[l][i - 1]][i - 1];
if (f[l][i]) ans = i;
}
}
cout << ans << "\n";
}
signed main() {
// freopen("input.in", "r", stdin);
int T = 1;
while (T--)
Main();
return 0;
}

浙公网安备 33010602011771号