結果
問題 | No.1269 I hate Fibonacci Number |
ユーザー |
![]() |
提出日時 | 2020-10-23 23:53:38 |
言語 | C++17 (gcc 13.3.0 + boost 1.87.0) |
結果 |
AC
|
実行時間 | 51 ms / 3,000 ms |
コード長 | 3,747 bytes |
コンパイル時間 | 2,382 ms |
コンパイル使用メモリ | 219,252 KB |
最終ジャッジ日時 | 2025-01-15 14:23:56 |
ジャッジサーバーID (参考情報) |
judge2 / judge5 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 3 |
other | AC * 36 |
ソースコード
#include <stdio.h>#include <bits/stdc++.h>#include <atcoder/modint>using namespace atcoder;using mint = modint1000000007;using namespace std;#define rep(i,n) for (int i = 0; i < (n); ++i)#define Inf 1000000000000000000long long L,R;vector<string> get(vector<long long> F){vector<string> S;rep(i,F.size()){S.push_back(to_string(F[i]));}while(true){bool f = false;rep(i,S.size()){rep(j,S.size()){if(j<=i)continue;rep(k,S[j].size()){if(k+S[i].size()>S[j].size())break;if(S[j].substr(k,S[i].size())==S[i]){S.erase(S.begin()+j);f=true;break;}}if(f)break;}if(f)break;}if(!f)break;}return S;}vector<mint> dp,ndp;template <typename T>struct trie{T init_value;struct node{vector<int> next;T v;T sum;int depth;node(int wordSize,T iv,int d){next.resize(wordSize,-1);v = iv;sum = iv;depth = d;}int link=-1;};vector<node> nodes;int wordSize;trie(int sz,T iv){init_value = iv;wordSize = sz;nodes.push_back(node(wordSize,init_value,0));}void add(string &S,T x,int cPos=0,int cNode=0){if(cPos==S.size()){nodes[cNode].v = func(nodes[cNode].v,x);return;}int c = encode(S[cPos]);if(nodes[cNode].next[c]==-1){nodes[cNode].next[c] = nodes.size();nodes.push_back(node(wordSize,init_value,nodes[cNode].depth+1));}int nextNode = nodes[cNode].next[c];add(S,x,cPos+1,nextNode);}void set_link(){nodes[0].link = 0;queue<int> Q;Q.push(0);while(Q.size()!=0){int now = Q.front();Q.pop();nodes[now].v = func(nodes[now].v,nodes[nodes[now].link].v);nodes[now].sum = func(nodes[now].sum,nodes[now].v);for(int i=0;i<wordSize;i++){int to = nodes[now].next[i];if(to==-1)continue;int x = now;while(x!=0){x = nodes[x].link;if(nodes[x].next[i]!=-1){x = nodes[x].next[i];break;}}nodes[to].link = x;nodes[to].sum = func(nodes[to].sum,nodes[now].sum);Q.push(to);}}}T query(string &S,int cPos = 0,int cNode=0){T ret = init_value;if(cPos==S.size())return ret;int c = encode(S[cPos]);int nextNode = nodes[cNode].next[c];if(nextNode==-1){if(nodes[cNode].link!=-1){if(cNode!=0)ret = func(ret,query(S,cPos,nodes[cNode].link));else ret = func(ret,query(S,cPos+1,cNode));}}else{ret = func(ret,nodes[nextNode].v);ret = func(ret,query(S,cPos+1,nextNode));}return ret;}void go(){rep(i,nodes.size()){rep(j,10){int cNode = i;int nextNode = nodes[cNode].next[j];while(nextNode == -1){if(nodes[cNode].link==-1){nextNode = 0;break;}else{cNode = nodes[cNode].link;nextNode = nodes[cNode].next[j];if(nextNode==-1 && cNode==0){nextNode = 0;break;}}}ndp[nextNode] += dp[i];}}rep(i,nodes.size()){if(nodes[i].v<0){ndp[i] = 0;}}}int encode(char c){return c-'0';}T func(T a,T b){return a+b;}};int main(){int N;cin>>N>>L>>R;vector<long long> F(2,1);while(true){if(F.back() > R){F.pop_back();break;}F.push_back(F.back() + F[F.size()-2]);}while(F.size()>0&&F[0] < L)F.erase(F.begin());vector<string> S = get(F);mint ans = 0;if(S.size()==0){ans = 1;rep(i,N)ans *= 10;ans--;}else{trie<int> T(10,0);rep(i,S.size()){T.add(S[i],-1);}T.set_link();dp.resize(T.nodes.size(),0);dp[0] = 1;rep(i,N){ndp.assign(T.nodes.size(),0);T.go();swap(dp,ndp);}rep(i,dp.size())ans += dp[i];ans --;}cout<<ans.val()<<endl;return 0;}