Run ID 作者 问题 语言 测评结果 分数 时间 内存 代码长度 提交时间
37451 a+qazolite 【S】T3 C++ 通过 100 1516 MS 780 KB 2205 2025-03-30 18:45:48

Tests(40/40):


// Author: Aquizahv #include <bits/stdc++.h> #define ll long long using namespace std; const int N = 1e5 + 5, LOGN = 20, M = 400, lmt = 200; int n, m, a[N]; int dp[2][LOGN][M]; int Mn1[2][M], *mn1[2] = {Mn1[0] + LOGN, Mn1[1] + LOGN}; // mul - div <= j int Mn2[2][M][LOGN], (*mn2[2])[LOGN] = {Mn2[0] + LOGN, Mn2[1] + LOGN}; // mul - div == j && div >= k int dig(int x) { int res = 0; while (x) { x >>= 1; res++; } return res; } int least_rem(int x, int y) { int res = 0; while (x > y) { x >>= 1, y >>= 1; res++; } return res; } void getmin(int &to, int fro) { to = min(to, fro); } #define minset(x) memset(x, 0x3f, sizeof(x)) int main() { cin >> n; for (int i = 1; i <= n; i++) scanf("%d", a + i); int cur = 0, lst = 1; minset(Mn1[cur]), minset(Mn2[cur]); for (int i = -18; i <= lmt; i++) { mn1[cur][i] = 0; for (int j = 0; j <= 18; j++) mn2[cur][i][j] = 0; } for (int i = 1; i <= n; i++) { swap(cur, lst); minset(dp[cur]), minset(Mn1[cur]), minset(Mn2[cur]); int dif = dig(a[i]) - dig(a[i - 1]), rem; for (int j = 0; ; j++) { int x = (a[i] >> j) << j; if (!x) break; if (dif >= 0) rem = least_rem(a[i - 1], x >> dif); else rem = least_rem(a[i - 1], x << (-dif)); for (int k = 0; k < lmt; k++) { getmin(dp[cur][j][k], j + k + min(mn1[lst][k - j + dif - 1], mn2[lst][k - j + dif][rem])); getmin(mn1[cur][k - j], dp[cur][j][k]); getmin(mn2[cur][k - j][j], dp[cur][j][k]); } } getmin(dp[cur][dig(a[i])][0], min(mn1[lst][-dig(a[i - 1])], mn2[lst][-dig(a[i - 1])][0])); for (int j = -17; j <= lmt; j++) { getmin(mn1[cur][j], mn1[cur][j - 1]); for (int k = 17; k >= 0; k--) getmin(mn2[cur][j][k], mn2[cur][j][k + 1]); } } cout << mn1[cur][lmt] << endl; return 0; }


测评信息: