結果
問題 | No.801 エレベーター |
ユーザー |
![]() |
提出日時 | 2019-03-17 21:49:14 |
言語 | C++11 (gcc 13.3.0) |
結果 |
AC
|
実行時間 | 709 ms / 2,000 ms |
コード長 | 4,369 bytes |
コンパイル時間 | 1,513 ms |
コンパイル使用メモリ | 165,068 KB |
実行使用メモリ | 5,376 KB |
最終ジャッジ日時 | 2024-07-07 21:44:19 |
合計ジャッジ時間 | 13,077 ms |
ジャッジサーバーID (参考情報) |
judge2 / judge1 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 3 |
other | AC * 26 |
ソースコード
#include <bits/stdc++.h>using namespace std;typedef long long ll;template<int M, bool IsPrime = false>class Modulo {int n;static typename std::enable_if<IsPrime, ll>::type inv(ll a, ll p) {return (a == 1 ? 1 : (1 - p * inv(p % a, a)) / a + p);}public:Modulo() : n(0) { ; }Modulo(int m) : n(m) {if (n >= M)n %= M;else if (n < 0)n = (n % M + M) % M;}Modulo(ll m) {if (m >= M)m %= M;else if (m < 0)m = (m % M + M) % M;n = m;}explicit operator int() const { return n; }explicit operator ll() const { return n; }bool operator==(const Modulo &a) const { return n == a.n; }Modulo &operator+=(const Modulo &a) {n += a.n;if (n >= M) n -= M;return *this;}Modulo &operator-=(const Modulo &a) {n -= a.n;if (n < 0) n += M;return *this;}Modulo &operator*=(const Modulo &a) {n = (ll(n) * a.n) % M;return *this;}Modulo operator+(const Modulo &a) const {Modulo res = *this;return res += a;}Modulo operator-(const Modulo &a) const {Modulo res = *this;return res -= a;}Modulo operator-() const { return Modulo(0) - *this; }Modulo operator*(const Modulo &a) const {Modulo res = *this;return res *= a;}Modulo operator^(ll m) const {if (m == 0) return Modulo(1);const Modulo a = *this;Modulo res = (a * a) ^(m / 2);return m % 2 ? res * a : res;}typename std::enable_if<IsPrime, Modulo>::typeoperator/(const Modulo &a) const {return *this * inv(ll(a), M);}typename std::enable_if<IsPrime, Modulo>::type operator/=(const Modulo &a) {return *this *= inv(ll(a), M);}friend bool is_zero(const Modulo &x) { return int(x) == 0; }friend int abs(const Modulo &x) { return int(x); }static Modulo fact(int n, bool sw = true) {static std::vector<Modulo> v1 = {1}, v2 = {1};if (n >= (int) v1.size()) {const int from = v1.size(), to = n + 1024;v1.reserve(to);v2.reserve(to);for (int i = from; i < to; ++i) {v1.push_back(v1.back() * Modulo<M, true>(i));v2.push_back(v2.back() / Modulo<M, true>(i));}}return sw ? v1[n] : v2[n];}static Modulo comb(int a, int b) {if (b < 0 || b > a) return 0;return Modulo::fact(a, true) * Modulo::fact(b, false) *Modulo::fact(a - b, false);}};typedef Modulo<1000000007, true> mInt;template<typename T>class FenwickTree {int n;std::vector<T> data;public:FenwickTree(int count) : n(count), data(count, 0) { ; }void add(int pos, const T &value) {assert(0 <= pos && pos < n);for (int i = pos; i < n; i |= i + 1) data[i] += value;}// 区間 [0, pos) 番目の範囲の和を求める.(pos = 0 のときは 0 を返す.)T sum(int pos) const {assert(0 <= pos && pos <= n);T res = 0;for (int i = pos - 1; i >= 0; i = (i & (i + 1)) - 1) {res += data[i];}return res;}// 区間 [l, r) 番目の範囲の和を求める.(l = r のときは 0 を返す.)T sum(int l, int r) const {assert(0 <= l && l <= r && r <= n);return sum(r) + (-sum(l));}using value_type = T;using update_type = T;};pair<int, int> seg[3010];int main() {int N, M, K;cin >> N >> M >> K;for (int i = 0; i < M; i++) {int a, b;cin >> a >> b;--a;seg[i] = {a, b};}FenwickTree<mInt> dp(N);dp.add(0, 1);for (int k = 0; k < K; k++) {FenwickTree<mInt> dp2(N);for (int j = 0; j < M; j++) {mInt tot = dp.sum(seg[j].first, seg[j].second);dp2.add(seg[j].first, tot);if( seg[j].second < N ) dp2.add(seg[j].second, -tot);}FenwickTree<mInt> dp3(N);for (int j = 0; j < N; j++) {dp3.add(j, dp2.sum(0, j + 1));}swap(dp, dp3);}cout << (ll) dp.sum(N - 1, N) << endl;return 0;}