結果
問題 | No.1043 直列大学 |
ユーザー |
![]() |
提出日時 | 2020-05-01 21:58:00 |
言語 | C++17(gcc12) (gcc 12.3.0 + boost 1.87.0) |
結果 |
AC
|
実行時間 | 30 ms / 2,000 ms |
コード長 | 4,609 bytes |
コンパイル時間 | 3,352 ms |
コンパイル使用メモリ | 113,816 KB |
最終ジャッジ日時 | 2025-01-10 04:46:14 |
ジャッジサーバーID (参考情報) |
judge2 / judge5 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 3 |
other | AC * 28 |
ソースコード
#include <iostream>#include <algorithm>#include <utility>#include <vector>#include <numeric>#include <cassert>template <class T, class U>inline bool chmin(T &lhs, const U &rhs) {if (lhs > rhs) {lhs = rhs;return true;}return false;}template <class T, class U>inline bool chmax(T &lhs, const U &rhs) {if (lhs < rhs) {lhs = rhs;return true;}return false;}// [l, r) from l to rstruct range {struct itr {int i;constexpr itr(int i_): i(i_) { }constexpr void operator ++ () { ++i; }constexpr int operator * () const { return i; }constexpr bool operator != (itr x) const { return i != x.i; }};const itr l, r;constexpr range(int l_, int r_): l(l_), r(std::max(l_, r_)) { }constexpr itr begin() const { return l; }constexpr itr end() const { return r; }};// [l, r) from r to lstruct revrange {struct itr {int i;constexpr itr(int i_): i(i_) { }constexpr void operator ++ () { --i; }constexpr int operator * () const { return i; }constexpr bool operator != (itr x) const { return i != x.i; }};const itr l, r;constexpr revrange(int l_, int r_): l(l_ - 1), r(std::max(l_, r_) - 1) { }constexpr itr begin() const { return r; }constexpr itr end() const { return l; }};template <class T>class modulo_int {public:static constexpr int mod = T::value;static_assert(mod > 0, "mod must be positive");private:long long value;constexpr void normalize() {value %= mod;if (value < 0) value += mod;}public:constexpr modulo_int(long long value_ = 0): value(value_) { normalize(); }constexpr modulo_int operator - () const { return modulo_int(mod - value); }constexpr modulo_int operator ~ () const { return power(mod - 2); }constexpr long long operator () () const { return value; }constexpr modulo_int operator + (const modulo_int &rhs) const { return modulo_int(*this) += rhs; }constexpr modulo_int &operator += (const modulo_int &rhs) {if ((value += rhs.value) >= mod) value -= mod;return (*this);}constexpr modulo_int operator - (const modulo_int &rhs) const { return modulo_int(*this) -= rhs; }constexpr modulo_int &operator -= (const modulo_int &rhs) {if ((value += mod - rhs.value) >= mod) value -= mod;return (*this);}constexpr modulo_int operator * (const modulo_int &rhs) const { return modulo_int(*this) *= rhs; }constexpr modulo_int &operator *= (const modulo_int &rhs) {(value *= rhs.value) %= mod;return (*this);}constexpr modulo_int operator / (const modulo_int &rhs) const { return modulo_int(*this) /= rhs; }constexpr modulo_int &operator /= (const modulo_int &rhs) {return (*this) *= ~rhs;}constexpr bool operator == (const modulo_int &rhs) const {return value == rhs();}constexpr bool operator != (const modulo_int &rhs) const {return value != rhs();}constexpr modulo_int power (uint64_t exp) const {modulo_int result(1), mult(*this);while (exp > 0) {if (exp & 1) result *= mult;mult *= mult;exp >>= 1;}return result;}friend std::istream &operator >> (std::istream &stream, modulo_int &lhs) {stream >> lhs.value;lhs.normalize();return stream;}friend std::ostream &operator << (std::ostream &stream, const modulo_int &rhs) {return stream << rhs.value;}};using modint = modulo_int<std::integral_constant<int, 1000000007>>;constexpr int mx = 1000;int main() {int N, M;std::cin >> N >> M;std::vector<int> V(N), R(M);for (int &x: V) {std::cin >> x;}for (int &x: R) {std::cin >> x;}int A, B;std::cin >> A >> B;std::vector<modint> vdp(N * mx + 1);vdp.front() = 1;for (int i: range(0, N)) {for (int j: revrange(0, vdp.size())) {if (j - V[i] >= 0) {vdp[j] += vdp[j - V[i]];}}}std::vector<modint> rdp(M * mx + 1);rdp.front() = 1;for (int i: range(0, M)) {for (int j: revrange(0, rdp.size())) {if (j - R[i] >= 0) {rdp[j] += rdp[j - R[i]];}}}std::vector<modint> sum(vdp.size() + 1);for (int i: range(0, vdp.size())) {sum[i + 1] += sum[i] + vdp[i];}modint ans;for (int i: range(0, rdp.size())) {long long ub = std::min((long long) B * i + 1, (long long) vdp.size());long long lb = std::min((long long) A * i, (long long) vdp.size());assert(0 <= ub && ub <= vdp.size());assert(0 <= lb && lb <= vdp.size());ans += (sum[ub] - sum[lb]) * rdp[i];}std::cout << ans - 1 << '\n';return 0;}