結果
問題 | No.1269 I hate Fibonacci Number |
ユーザー | okuraofvegetabl |
提出日時 | 2020-10-24 14:00:12 |
言語 | C++17 (gcc 12.3.0 + boost 1.83.0) |
結果 |
AC
|
実行時間 | 130 ms / 3,000 ms |
コード長 | 8,236 bytes |
コンパイル時間 | 2,970 ms |
コンパイル使用メモリ | 224,304 KB |
実行使用メモリ | 31,488 KB |
最終ジャッジ日時 | 2024-07-21 15:14:08 |
合計ジャッジ時間 | 4,296 ms |
ジャッジサーバーID (参考情報) |
judge5 / judge4 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 2 ms
6,820 KB |
testcase_01 | AC | 2 ms
6,940 KB |
testcase_02 | AC | 3 ms
6,944 KB |
testcase_03 | AC | 2 ms
6,940 KB |
testcase_04 | AC | 2 ms
6,940 KB |
testcase_05 | AC | 2 ms
6,940 KB |
testcase_06 | AC | 2 ms
6,940 KB |
testcase_07 | AC | 2 ms
6,944 KB |
testcase_08 | AC | 2 ms
6,944 KB |
testcase_09 | AC | 1 ms
6,944 KB |
testcase_10 | AC | 2 ms
6,944 KB |
testcase_11 | AC | 2 ms
6,944 KB |
testcase_12 | AC | 2 ms
6,944 KB |
testcase_13 | AC | 38 ms
11,136 KB |
testcase_14 | AC | 47 ms
13,440 KB |
testcase_15 | AC | 7 ms
6,944 KB |
testcase_16 | AC | 36 ms
10,752 KB |
testcase_17 | AC | 3 ms
6,940 KB |
testcase_18 | AC | 37 ms
11,392 KB |
testcase_19 | AC | 27 ms
9,344 KB |
testcase_20 | AC | 7 ms
6,940 KB |
testcase_21 | AC | 23 ms
8,192 KB |
testcase_22 | AC | 20 ms
7,424 KB |
testcase_23 | AC | 23 ms
8,064 KB |
testcase_24 | AC | 11 ms
6,944 KB |
testcase_25 | AC | 15 ms
6,940 KB |
testcase_26 | AC | 3 ms
6,940 KB |
testcase_27 | AC | 2 ms
6,944 KB |
testcase_28 | AC | 7 ms
6,940 KB |
testcase_29 | AC | 13 ms
6,940 KB |
testcase_30 | AC | 6 ms
6,940 KB |
testcase_31 | AC | 63 ms
15,872 KB |
testcase_32 | AC | 14 ms
6,940 KB |
testcase_33 | AC | 130 ms
31,488 KB |
testcase_34 | AC | 2 ms
6,944 KB |
testcase_35 | AC | 6 ms
6,940 KB |
testcase_36 | AC | 2 ms
6,944 KB |
testcase_37 | AC | 2 ms
6,944 KB |
testcase_38 | AC | 2 ms
6,944 KB |
ソースコード
// #pragma GCC optimize("unroll-loops", "omit-frame-pointer", "inline") // #pragma GCC option("arch=native", "tune=native", "no-zero-upper") // #pragma GCC // target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,avx2,tune=native") // #pragma GCC optimize("Ofast") // #pragma GCC optimize("tree-vectorize","openmp","predictive-commoning") // #pragma GCC option("D_GLIBCXX_PARALLEL","openmp") // #pragma GCC optimize("O3") // #pragma GCC target("avx2") #include <bits/stdc++.h> using namespace std; typedef long long ll; typedef pair<int, int> P; #define eps 1e-9 #define INF 2000000000 // 2e9 #define LLINF 2000000000000000000ll // 2e18 (llmax:9e18) #define all(x) (x).begin(), (x).end() #define sq(x) ((x) * (x)) #ifndef LOCAL #define dmp(...) ; #else #define dmp(...) \ cerr << "[ " << #__VA_ARGS__ << " ] : " << dump_str(__VA_ARGS__) << endl #endif // ---------------- Utility ------------------ template <class T> bool chmin(T &a, const T &b) { if (a <= b) return false; a = b; return true; } template <class T> bool chmax(T &a, const T &b) { if (a >= b) return false; a = b; return true; } template <class T> using MaxHeap = priority_queue<T>; template <class T> using MinHeap = priority_queue<T, vector<T>, greater<T>>; template <class T> vector<T> vect(int len, T elem) { return vector<T>(len, elem); } // ----------------- Input ------------------- template <class T, class U> istream &operator>>(istream &is, pair<T, U> &p) { is >> p.first >> p.second; return is; } template <class T> istream &operator>>(istream &is, vector<T> &vec) { for (int i = 0; i < vec.size(); i++) is >> vec[i]; return is; } // ----------------- Output ------------------ template <class T, class U> ostream &operator<<(ostream &os, const pair<T, U> &p) { os << p.first << ',' << p.second; return os; } template <class T> ostream &operator<<(ostream &os, const vector<T> &v) { for (const T &e : v) os << e << " "; return os; } template <class T> ostream &operator<<(ostream &os, const deque<T> &d) { for (const T &e : d) os << e << " "; return os; } template <class T> ostream &operator<<(ostream &os, const set<T> &s) { os << "{ "; for (const T &e : s) os << e << " "; os << "}"; return os; } template <class T> ostream &operator<<(ostream &os, const multiset<T> &s) { os << "{ "; for (const T &e : s) os << e << " "; os << "}"; return os; } template <class T, class U> ostream &operator<<(ostream &os, const map<T, U> &m) { os << "{ "; for (const auto &[key, val] : m) os << "( " << key << " -> " << val << " ) "; os << "}"; return os; } void dump_str_rec(ostringstream &) {} template <class Head, class... Tail> void dump_str_rec(ostringstream &oss, Head &&head, Tail &&... tail) { oss << ", " << head; dump_str_rec(oss, forward<Tail>(tail)...); } template <class T, class... U> string dump_str(T &&arg, U &&... args) { ostringstream oss; oss << arg; dump_str_rec(oss, forward<T>(args)...); return oss.str(); } // --------------- Fast I/O ------------------ void fastio() { cin.tie(0); ios::sync_with_stdio(0); cout << fixed << setprecision(20); } // ------------ End of template -------------- #define endl "\n" struct AhoCorasick { const static int alphabet_size = 10; const int root = 0; const char base = '0'; AhoCorasick() : T(1) {} AhoCorasick(const vector<string> &ss) : T(1) { for (const string &s : ss) add_string(s); build(); } struct Node { vector<int> child; // children of this node in Trie bool leaf; int par; // parent char par_c; // character on the edge from parent to this node int suf_link; // suffix link vector<int> go; // transition of the automaton int match_count; // the number of matches of this state Node(int par = -1, char par_c = '$') : leaf(false), par(par), par_c(par_c), suf_link(-1) { child.assign(alphabet_size, -1); go.assign(alphabet_size, -1); } }; vector<Node> T; void add_string(const string &s) { int v = root; for (char ch : s) { int c = ch - base; if (T[v].child[c] == -1) { T[v].child[c] = T.size(); T.emplace_back(v, ch); } v = T[v].child[c]; } T[v].leaf = true; } int suf_link(int v) { if (T[v].suf_link == -1) { if (v == root || T[v].par == root) { T[v].suf_link = root; } else { int par_suf_link = suf_link(T[v].par); T[v].suf_link = go(par_suf_link, T[v].par_c); } } return T[v].suf_link; } int go(int v, char ch) { int c = ch - base; if (T[v].go[c] == -1) { if (T[v].child[c] != -1) T[v].go[c] = T[v].child[c]; else T[v].go[c] = (v == root) ? root : go(suf_link(v), ch); } return T[v].go[c]; } int match_count(int v) { if (v == root) T[v].match_count = 0; else { T[v].match_count = match_count(suf_link(v)) + (T[v].leaf ? 1 : 0); } return T[v].match_count; } void build() { for (int v = 0; v < T.size(); v++) { suf_link(v); match_count(v); for (int i = 0; i < alphabet_size; i++) go(v, base + i); } } Node &operator[](int v) { return T[v]; } int size() const { return T.size(); } }; template <int MOD> // if inv is needed, this shold be prime. struct ModInt { ll val; ModInt() : val(0ll) {} ModInt(const ll &v) : val(((v % MOD) + MOD) % MOD) {} bool operator==(const ModInt &x) const { return val == x.val; } bool operator!=(const ModInt &x) const { return !(*this == x); } bool operator<(const ModInt &x) const { return val < x.val; } bool operator>(const ModInt &x) const { return val > x.val; } bool operator>=(const ModInt &x) const { return !(*this < x); } bool operator<=(const ModInt &x) const { return !(*this > x); } ModInt operator-() const { return ModInt(MOD - val); } ModInt inv() const { return this->pow(MOD - 2); } ModInt &operator+=(const ModInt &x) { if ((val += x.val) >= MOD) val -= MOD; return *this; } ModInt &operator-=(const ModInt &x) { if ((val += MOD - x.val) >= MOD) val -= MOD; return *this; } ModInt &operator*=(const ModInt &x) { (val *= x.val) %= MOD; return *this; } ModInt &operator/=(const ModInt &x) { return *this *= x.inv(); }; ModInt operator+(const ModInt &x) const { return ModInt(*this) += x; } ModInt operator-(const ModInt &x) const { return ModInt(*this) -= x; } ModInt operator*(const ModInt &x) const { return ModInt(*this) *= x; } ModInt operator/(const ModInt &x) const { return ModInt(*this) /= x; } friend istream &operator>>(istream &i, ModInt &x) { ll v; i >> v; x = v; return i; } friend ostream &operator<<(ostream &o, const ModInt &x) { o << x.val; return o; } ModInt pow(ll x) const { auto res = ModInt(1ll); auto b = *this; while (x) { if (x & 1) res *= b; x >>= 1; b *= b; } return res; } }; template <int MOD> ModInt<MOD> pow(ModInt<MOD> a, ll x) { ModInt<MOD> res = ModInt<MOD>(1ll); while (x) { if (x & 1) res *= a; x >>= 1; a *= a; } return res; } constexpr int MOD = 1e9 + 7; // constexpr int MOD = 998244353; using mint = ModInt<MOD>; void solve() { int N; ll L, R; cin >> N >> L >> R; ll x = 1, y = 1; vector<string> vs; while (LLINF - x >= y) { if (L <= y && y <= R) vs.push_back(to_string(y)); ll z = x + y; x = y; y = z; } AhoCorasick ac(vs); auto dp = vect(N + 1, vect(ac.size(), mint(0))); dp[0][0] = mint(1); for (int i = 0; i < N; i++) { for (int j = 0; j < ac.size(); j++) { for (int k = 0; k < 10; k++) { int next_state = ac.go(j, '0' + k); if (ac[next_state].match_count > 0) continue; dp[i + 1][next_state] += dp[i][j]; } } } mint ans(0); for (int j = 0; j < ac.size(); j++) ans += dp[N][j]; ans -= mint(1); cout << ans << endl; return; } int main() { fastio(); solve(); // int t; cin >> t; while(t--)solve(); // int t; cin >> t; // for(int i=1;i<=t;i++){ // cout << "Case #" << i << ": "; // solve(); // } return 0; }