八芒星

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;
}
posted @ 2025-11-06 17:21  FRZ_29  阅读(1)  评论(0)    收藏  举报
2025-7-11 11:06:15 TOP-BOTTOM-THEME
Enable/Disable Transition
Copyright © 2023 ~ 2025 FRZ - 1801534592@qq.com
Illustration from たとえ,by Rella