結果
| 問題 | No.1269 I hate Fibonacci Number |
| コンテスト | |
| ユーザー |
cureskol
|
| 提出日時 | 2024-03-31 20:45:46 |
| 言語 | C++17(gcc12) (gcc 12.3.0 + boost 1.87.0) |
| 結果 |
AC
|
| 実行時間 | 381 ms / 3,000 ms |
| コード長 | 3,659 bytes |
| コンパイル時間 | 9,088 ms |
| コンパイル使用メモリ | 290,984 KB |
| 最終ジャッジ日時 | 2025-02-20 18:20:47 |
|
ジャッジサーバーID (参考情報) |
judge5 / judge2 |
| 純コード判定しない問題か言語 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 3 |
| other | AC * 36 |
ソースコード
#include <bits/stdc++.h>
template <size_t SIGMA = 26, char MARGIN = 'a'> class Trie {
struct Node {
std::array<int, SIGMA> nxt;
Node() { std::ranges::fill(nxt, -1); }
};
protected:
std::vector<Node> nodes;
public:
Trie() : nodes(1, Node()) {}
int &nxt(size_t v, char c) { return nodes[v].nxt[c - MARGIN]; }
size_t add(const std::string &s) {
size_t now = 0;
for (char c : s) {
if (nxt(now, c) < 0) {
nxt(now, c) = nodes.size();
nodes.push_back(Node());
}
now = nxt(now, c);
}
return now;
}
std::vector<size_t> add(const std::vector<std::string> &v) {
std::vector<size_t> ret;
ret.reserve(v.size());
for (const std::string &s : v)
ret.push_back(add(s));
return ret;
}
};
template <size_t SIGMA = 26, char MARGIN = 'a'>
class AhoCorasick : Trie<SIGMA, MARGIN> {
using super = Trie<SIGMA, MARGIN>;
using super::nodes;
std::vector<std::map<size_t, uint32_t>> vertex_counts;
public:
using super::nxt;
using super::Trie;
std::vector<size_t> add(const std::vector<std::string> &v) {
auto ret = super::add(v);
size_t n = nodes.size();
vertex_counts.resize(n);
std::vector<bool> exist(n, false);
for (size_t v : ret)
exist[v] = true;
std::vector<size_t> suffix(n);
std::queue<size_t> que;
que.push(0);
while (que.size()) {
size_t v = que.front();
que.pop();
if (v) {
if (exist[v])
vertex_counts[v][v]++;
for (const auto &[key, value] : vertex_counts[suffix[v]])
vertex_counts[v][key] += value;
}
for (size_t i = 0; i < SIGMA; i++) {
int &to = nodes[v].nxt[i];
if (~to) {
suffix[to] = v ? nodes[suffix[v]].nxt[i] : 0;
que.push(to);
} else
to = v ? nodes[suffix[v]].nxt[i] : 0;
}
}
return ret;
}
const std::map<size_t, uint32_t> &count(size_t v) const {
return vertex_counts[v];
}
std::map<size_t, uint32_t> path(const std::string &s) const {
std::map<size_t, uint32_t> ret;
size_t v = 0;
for (const char &c : s) {
v = nxt(v, c);
for (const auto &[key, value] : vertex_counts)
ret[key] += value;
}
return ret;
}
};
#include <atcoder/modint>
using mint = atcoder::modint1000000007;
int main() {
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr);
int n;
std::cin >> n;
uint64_t l, r;
std::cin >> l >> r;
std::vector<uint64_t> fib{1, 2};
while (fib.back() < r)
fib.push_back(fib[fib.size() - 2] + fib[fib.size() - 1]);
std::vector<std::string> v;
for (const auto &x : fib) {
if (std::clamp(x, l, r) != x)
continue;
v.push_back(std::to_string(x));
}
AhoCorasick<10, '0'> T;
T.add(v);
std::map<size_t, mint> dp{{0, 1}};
while (n--) {
std::map<size_t, mint> nxt;
for (const auto &[v, val] : dp) {
for (char c = '0'; c <= '9'; c++) {
size_t to = T.nxt(v, c);
if (T.count(to).size())
continue;
nxt[to] += val;
}
}
dp = nxt;
}
mint ans = -1;
for (const auto &[key, val] : dp)
ans += val;
std::cout << ans.val() << '\n';
}
cureskol