結果

問題 No.1269 I hate Fibonacci Number
ユーザー LayCurse
提出日時 2020-10-23 22:44:24
言語 C++17
(gcc 13.3.0 + boost 1.87.0)
結果
AC  
実行時間 67 ms / 3,000 ms
コード長 9,895 bytes
コンパイル時間 2,728 ms
コンパイル使用メモリ 214,112 KB
最終ジャッジ日時 2025-01-15 13:37:47
ジャッジサーバーID
(参考情報)
judge5 / judge1
このコードへのチャレンジ
(要ログイン)
ファイルパターン 結果
sample AC * 3
other AC * 36
権限があれば一括ダウンロードができます

ソースコード

diff #
プレゼンテーションモードにする

#pragma GCC optimize ("Ofast")
#include<bits/stdc++.h>
using namespace std;
#define MD (1000000007U)
void*wmem;
char memarr[96000000];
template<class T> void malloc1d(T **arr, int x){
(*arr) = (T*)malloc(x*sizeof(T));
}
template<class T> void free1d(T *arr){
free(arr);
}
template<class T> void malloc2d(T ***arr, int x, int y){
int i;
(*arr) = (T**)malloc(x*sizeof(T*));
(*arr)[0] = (T*)malloc(x*y*sizeof(T));
int jbtyPBGc = x;
for(i=(1);i<(jbtyPBGc);i++){
(*arr)[i]=(*arr)[i-1]+y;
}
}
template<class T> void free2d(T **arr){
free(arr[0]);
free(arr);
}
struct Modint{
unsigned val;
Modint(){
val=0;
}
Modint(int a){
val = ord(a);
}
Modint(unsigned a){
val = ord(a);
}
Modint(long long a){
val = ord(a);
}
Modint(unsigned long long a){
val = ord(a);
}
inline unsigned ord(unsigned a){
return a%MD;
}
inline unsigned ord(int a){
a %= (int)MD;
if(a < 0){
a += MD;
}
return a;
}
inline unsigned ord(unsigned long long a){
return a%MD;
}
inline unsigned ord(long long a){
a %= (int)MD;
if(a < 0){
a += MD;
}
return a;
}
inline unsigned get(){
return val;
}
inline Modint &operator+=(Modint a){
val += a.val;
if(val >= MD){
val -= MD;
}
return *this;
}
inline Modint &operator-=(Modint a){
if(val < a.val){
val = val + MD - a.val;
}
else{
val -= a.val;
}
return *this;
}
inline Modint &operator*=(Modint a){
val = ((unsigned long long)val*a.val)%MD;
return *this;
}
inline Modint &operator/=(Modint a){
return *this *= a.inverse();
}
inline Modint operator+(Modint a){
return Modint(*this)+=a;
}
inline Modint operator-(Modint a){
return Modint(*this)-=a;
}
inline Modint operator*(Modint a){
return Modint(*this)*=a;
}
inline Modint operator/(Modint a){
return Modint(*this)/=a;
}
inline Modint operator+(int a){
return Modint(*this)+=Modint(a);
}
inline Modint operator-(int a){
return Modint(*this)-=Modint(a);
}
inline Modint operator*(int a){
return Modint(*this)*=Modint(a);
}
inline Modint operator/(int a){
return Modint(*this)/=Modint(a);
}
inline Modint operator+(long long a){
return Modint(*this)+=Modint(a);
}
inline Modint operator-(long long a){
return Modint(*this)-=Modint(a);
}
inline Modint operator*(long long a){
return Modint(*this)*=Modint(a);
}
inline Modint operator/(long long a){
return Modint(*this)/=Modint(a);
}
inline Modint operator-(void){
Modint res;
if(val){
res.val=MD-val;
}
else{
res.val=0;
}
return res;
}
inline operator bool(void){
return val!=0;
}
inline operator int(void){
return get();
}
inline operator long long(void){
return get();
}
inline Modint inverse(){
int a = val;
int b = MD;
int u = 1;
int v = 0;
int t;
Modint res;
while(b){
t = a / b;
a -= t * b;
swap(a, b);
u -= t * v;
swap(u, v);
}
if(u < 0){
u += MD;
}
res.val = u;
return res;
}
inline Modint pw(unsigned long long b){
Modint a(*this);
Modint res;
res.val = 1;
while(b){
if(b&1){
res *= a;
}
b >>= 1;
a *= a;
}
return res;
}
inline bool operator==(int a){
return ord(a)==val;
}
inline bool operator!=(int a){
return ord(a)!=val;
}
}
;
inline Modint operator+(int a, Modint b){
return Modint(a)+=b;
}
inline Modint operator-(int a, Modint b){
return Modint(a)-=b;
}
inline Modint operator*(int a, Modint b){
return Modint(a)*=b;
}
inline Modint operator/(int a, Modint b){
return Modint(a)/=b;
}
inline Modint operator+(long long a, Modint b){
return Modint(a)+=b;
}
inline Modint operator-(long long a, Modint b){
return Modint(a)-=b;
}
inline Modint operator*(long long a, Modint b){
return Modint(a)*=b;
}
inline Modint operator/(long long a, Modint b){
return Modint(a)/=b;
}
inline int my_getchar_unlocked(){
static char buf[1048576];
static int s = 1048576;
static int e = 1048576;
if(s == e && e == 1048576){
e = fread_unlocked(buf, 1, 1048576, stdin);
s = 0;
}
if(s == e){
return EOF;
}
return buf[s++];
}
inline void rd(int &x){
int k;
int m=0;
x=0;
for(;;){
k = my_getchar_unlocked();
if(k=='-'){
m=1;
break;
}
if('0'<=k&&k<='9'){
x=k-'0';
break;
}
}
for(;;){
k = my_getchar_unlocked();
if(k<'0'||k>'9'){
break;
}
x=x*10+k-'0';
}
if(m){
x=-x;
}
}
inline void rd(long long &x){
int k;
int m=0;
x=0;
for(;;){
k = my_getchar_unlocked();
if(k=='-'){
m=1;
break;
}
if('0'<=k&&k<='9'){
x=k-'0';
break;
}
}
for(;;){
k = my_getchar_unlocked();
if(k<'0'||k>'9'){
break;
}
x=x*10+k-'0';
}
if(m){
x=-x;
}
}
struct MY_WRITER{
char buf[1048576];
int s;
int e;
MY_WRITER(){
s = 0;
e = 1048576;
}
~MY_WRITER(){
if(s){
fwrite_unlocked(buf, 1, s, stdout);
}
}
}
;
MY_WRITER MY_WRITER_VAR;
void my_putchar_unlocked(int a){
if(MY_WRITER_VAR.s == MY_WRITER_VAR.e){
fwrite_unlocked(MY_WRITER_VAR.buf, 1, MY_WRITER_VAR.s, stdout);
MY_WRITER_VAR.s = 0;
}
MY_WRITER_VAR.buf[MY_WRITER_VAR.s++] = a;
}
inline void wt_L(char a){
my_putchar_unlocked(a);
}
inline void wt_L(int x){
int s=0;
int m=0;
char f[10];
if(x<0){
m=1;
x=-x;
}
while(x){
f[s++]=x%10;
x/=10;
}
if(!s){
f[s++]=0;
}
if(m){
my_putchar_unlocked('-');
}
while(s--){
my_putchar_unlocked(f[s]+'0');
}
}
inline void wt_L(Modint x){
int i;
i = (int)x;
wt_L(i);
}
template<class T, class S> inline int Digit_L(T n, S b){
int res = 0;
while(n){
res++;
n /= b;
}
return res;
}
template<class T, class S> inline int Digit_L(T n, S res[]){
int sz = 0;
while(n){
res[sz++] = n % 10;
n /= 10;
}
return sz;
}
template<class S> struct AhoCorasick_Sum{
int node;
int mem;
int alphabet;
int**nx;
int*failed;
S*sum;
void init(void){
int i;
node = 1;
for(i=(0);i<(alphabet);i++){
nx[0][i] = -1;
}
failed[0] = 0;
sum[0] = 0;
}
void malloc(const int n, const int k){
int i;
malloc2d(&nx,n,k);
malloc1d(&failed,n);
malloc1d(&sum,n);
node = n;
alphabet = k;
init();
}
void free(void){
free2d(nx);
free1d(failed);
free1d(sum);
}
template<class T> void addWord(const T word[], const int len, S val){
int i;
int j;
int k;
int now = 0;
for(i=(0);i<(len);i++){
if(nx[now][word[i]]==-1){
k = node++;
nx[now][word[i]] = k;
for(j=(0);j<(alphabet);j++){
nx[k][j] = -1;
}
sum[k] = 0;
}
now = nx[now][word[i]];
}
sum[now] += val;
}
void construct(void *mem = wmem){
int i;
int j;
int k;
int now;
int*q;
int qs;
int qe;
q = (int*) mem;
qs = qe = 0;
now = 0;
for(k=(0);k<(alphabet);k++){
if(nx[now][k] != -1){
q[qe++] = nx[now][k];
failed[ nx[now][k] ] = now;
}
}
while(qs < qe){
now = q[qs++];
for(k=(0);k<(alphabet);k++){
if(nx[now][k] != -1){
i = failed[now];
while(i){
if(nx[i][k] != -1){
break;
}
i = failed[i];
}
if(nx[i][k] != -1){
i = nx[i][k];
}
failed[ nx[now][k] ] = i;
sum[ nx[now][k] ] += sum[i];
q[qe++] = nx[now][k];
}
}
}
}
template<class T> inline int next(const int n, const T c){
int i;
int now;
now = n;
if(nx[n][c]!=-1){
return nx[n][c];
}
while(now && nx[now][c]==-1){
now=failed[now];
}
if(nx[now][c]!=-1){
now = nx[now][c];
}
return nx[n][c] = now;
}
}
;
AhoCorasick_Sum<int> aho;
Modint dp[1000];
Modint nx[1000];
int main(){
int cTE1_r3A;
wmem = memarr;
int N;
rd(N);
long long L;
rd(L);
long long R;
rd(R);
int ds;
int d[100];
int node;
int i;
int j;
int k;
long long a = 1;
long long b = 1;
aho.malloc(1000, 10);
while(a <= R){
{
auto Q5VJL1cS = (b);
auto e98WHCEY = (a+b);
a = Q5VJL1cS;
b = e98WHCEY;
}
if(L <= a && a <= R){
ds =Digit_L(a, d);
aho.addWord(d, ds, 1);
}
}
aho.construct();
node = aho.node;
dp[0] = 1;
for(cTE1_r3A=(0);cTE1_r3A<(N);cTE1_r3A++){
for(i=(0);i<(node);i++){
nx[i] = 0;
}
for(i=(0);i<(node);i++){
for(j=(0);j<(10);j++){
k = aho.next(i,j);
if(aho.sum[k]){
continue;
}
nx[k] += dp[i];
}
}
for(i=(0);i<(node);i++){
dp[i] = nx[i];
}
}
{
int V9aVTaxx;
Modint APIVbQlN;
if(node==0){
APIVbQlN = 0;
}
else{
APIVbQlN = dp[0];
for(V9aVTaxx=(1);V9aVTaxx<(node);V9aVTaxx++){
APIVbQlN += dp[V9aVTaxx];
}
}
wt_L(APIVbQlN-1);
wt_L('\n');
}
return 0;
}
// cLay varsion 20201018-2
// --- original code ---
// AhoCorasick_Sum<int> aho;
// Modint dp[1000], nx[1000];
// {
// int @N; ll @L, @R;
// int ds, d[100], node, i, j, k;
// ll a = 1, b = 1;
//
// aho.malloc(1000, 10);
//
// while(a <= R){
// (a,b) = (b,a+b);
// if(L <= a <= R){
// ds = Digit(a, d);
// aho.addWord(d, ds, 1);
// }
// }
// aho.construct();
//
// node = aho.node;
// dp[0] = 1;
// rep(N){
// rep(i,node) nx[i] = 0;
// rep(i,node) rep(j,10){
// k = aho.next(i,j);
// if(aho.sum[k]) continue;
// nx[k] += dp[i];
// }
// rep(i,node) dp[i] = nx[i];
// }
//
// wt(sum(dp(node))-1);
// }
הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
0