Skip to content

Line of Battle

Problem Description

Yun-Nung (Vivian) Chen's website

Concept

  • dynamic programming
  • binary search

Code

#include <bits/stdc++.h>

namespace ada {

class Xoroshiro128 {
 public:
  using result_type = uint32_t;
  static constexpr result_type(min)() { return 0; }
  static constexpr result_type(max)() { return UINT32_MAX; }
  static inline result_type rotl(const result_type x, int k) {
    return (x << k) | (x >> (32 - k));
  }
  Xoroshiro128() : Xoroshiro128(1, 2, 3, 4) {}
  Xoroshiro128(result_type a, result_type b, result_type c, result_type d)
      : s{a, b, c, d} {}
  result_type operator()() {
    const result_type result = rotl(s[0] + s[3], 7) + s[0];
    const result_type t = s[1] << 9;
    s[2] ^= s[0];
    s[3] ^= s[1];
    s[1] ^= s[2];
    s[0] ^= s[3];
    s[2] ^= t;
    s[3] = rotl(s[3], 11);
    return result;
  }

 private:
  std::array<result_type, 4> s;
};

namespace {
int c_lead, c_team;
Xoroshiro128 rng;
}  // namespace

int Init() {
  int n;
  uint32_t s1, s2, s3, s4;
  std::cin >> n >> c_lead >> c_team >> s1 >> s2 >> s3 >> s4;
  rng = Xoroshiro128(s1, s2, s3, s4);
  return n;
}

int GetLeadership() { return uint64_t(rng()) * c_lead >> 32; }

int GetTeamValue() {
  int tmp = int(uint64_t(rng()) * c_team >> 32) + 1;
  return int(c_team / sqrt(tmp));
}

}  // namespace ada

#define IOS {ios::sync_with_stdio(false);cin.tie(nullptr);}
using namespace std;
using LL = int64_t;
using ULL = uint64_t;
using LD = long double;
using pii = pair<int, int>;

constexpr int MAXN = 2e6+5;
constexpr int MOD = 1e9+7;

int n;
int lead[MAXN], team[MAXN];
int dp[MAXN], dp2[MAXN];
LL psum[MAXN];

int my_bsearch(LL x) {
    int l = 1, r = n+1;
    while ( l + 1 < r ) {
        int m = (l + r) >> 1;
        (x < psum[m] ? r : l) = m;
    }
    return r;
}

int main()
{
    IOS;
    n = ada::Init();
    for (int i = 1; i <= n; i++) lead[i] = ada::GetLeadership();
    for (int i = 1; i <= n; i++) team[i] = ada::GetTeamValue();

    for ( int i = 1; i <= n; i++)
        psum[i] = psum[i-1] + team[i];

    dp2[n+1] = 1;
    for ( int i = n; i >= 1; i--) {
        int p = my_bsearch(lead[i] + psum[i]);
        dp[i] = (dp2[i + 1] - dp2[p + 1]);
        dp[i] +=  dp[i] < 0 ? MOD : 0;
        dp2[i] = (dp[i] + dp2[i+1]);
        dp2[i] -= dp2[i] >= MOD ? MOD : 0;
    }
    cout << dp[1] << '\n';
    return 0;
}