八芒星
P12000 扶苏出勤日记
二分搜索答案 \(a\)。注意到第 \(i\) 天时,以前没用完的钱的的最大汇率构成单调队列。模拟即可。
少考虑一种情况,导致赛时出错。
code
const int N = 1e6 + 6;
int T, n, a[N], b[N], l, r;
pii que[N];
bool check(i64 x) {
l = 0, r = -1; i64 res = 0;
rep(i, 1, n) {
pii e = {a[i], b[i]}; i64 need = x;
while (l <= r && que[r].first <= a[i]) e.second += que[r--].second;
que[++r] = e;
if (need <= res) {
res -= need;
continue;
}
need -= res, res = 0;
while (l <= r && need) {
i64 out = ceil(need * 1.0 / que[l].first);
if (out >= que[l].second) {
res += que[l].second * que[l].first;
if (res >= need) res -= need, need = 0;
else need -= res, res = 0;
l++;
} else {
que[l].second -= out;
res += out * que[l].first - need;
need = 0;
}
}
if (need) return 0;
}
return 1;
}
void solve() {
read(n);
rep(i, 1, n) read(a[i]);
rep(i, 1, n) read(b[i]);
i64 l = 0, r = 1e12;
while (l < r) {
i64 mid = (l + r + 1) >> 1;
if (check(mid)) l = mid;
else r = mid - 1;
}
write(l, '\n');
}
int main() {
read(T);
while (T--) solve();
return 0;
}
P14084 「CZOI-R7」敲击
转移矩阵显然。
特殊的是限制1,定义 \(cnt=\sum\limits_{i = 0}^{size(l) - 1}[l_i = 1]\),如果 \(m \ge cnt\),此时需要注意把第一块相等时的贡献加上。如果有 \(m \ge 2cnt\),有相等的情况一直存在,需要加上贡献。
对矩阵优化 DP 不熟练,导致想出正解没写出。
需要注意构造矩阵时的边界。
对部分特殊情况没有考虑。
code
int inv[N], fac[N], ifac[N];
string s;
i64 k;
int m, n;
struct matrix {
int a[N][N];
matrix() { memset(a, 0, sizeof(a)); }
void init() { rep(i, 0, n) a[i][i] = 1; }
friend matrix operator*(matrix a, matrix b) {
matrix c;
rep(i, 0, n) rep(k, 0, n) if (a.a[i][k]) rep(j, 0, n) if (b.a[k][j])
c.a[i][j] = (c.a[i][j] + ((i64)a.a[i][k] * b.a[k][j]) % mod) % mod;
return c;
}
} f, t;
matrix Pow(matrix a, i64 b) {
matrix res; res.init();
for (; b; b >>= 1) {
if (b & 1) res = res * a;
a = a * a;
}
return res;
}
void init() {
fac[0] = 1; rep(i, 1, N - 5) fac[i] = (i64)fac[i - 1] * i % mod;
inv[1] = 1; rep(i, 2, N - 5) inv[i] = (i64)(mod - mod / i) * inv[mod % i] % mod;
ifac[0] = 1; rep(i, 1, N - 5) ifac[i] = (i64)ifac[i - 1] * inv[i] % mod;
}
int C(int n, int m) {
if (n < m || n < 0 || m < 0) return 0;
return (i64)fac[n] * ifac[n - m] % mod * ifac[m] % mod;
}
int main() {
init();
cin >> s; n = s.size();
read(k, m); int cnt = 0;
rep(i, 0, n - 1) if (s[i] == '1') {
rep(j, 0, min(n - 1 - i, m - cnt)) {
int &p = f.a[0][cnt + j];
(p += C(n - i - 1, j)) %= mod;
}
cnt++;
}
rep(i, 0, n) rep(j, 0, n) if (i + j <= m)
t.a[i][j] = C(n, j);
n++;
if (cnt * 2 <= m) t.a[n][n] = 1;
if (cnt <= m) {
rep(i, 0, min(n - 1, m - cnt)) t.a[n][i] = f.a[0][i];
f.a[0][n] = 1;
}
f = (f * Pow(t, k - 1));
int ans = 0;
rep(i, 0, n) (ans += f.a[0][i]) %= mod;
write(ans, '\n');
return 0;
}
浙公网安备 33010602011771号