NEUOJ 短信文字识别

题面

阿诚的胳膊被卡住了,拔不出来。不过身边有一台实体按键的手机,这样就可以盲打发短信来求救了(真庆幸不是触屏手机),但是这个手机发送的日文短信。即使看不见画面也应该能发邮件。
我认为朋友们很聪明,他们会给我正确的解释,但我现在发送的信息可能与我真正想发送的信息不同。这种手机字符输入方法与广泛使用的方法相同,例如,使用“1”按钮输入“あ”行的平假名字符。“1”代表“あ”,“11”代表“い”,以此类推,“11111”代表“お”。平假名是循环的,即“111111”也是“あ”。“か”行使用“2”,“さ”行使用“3”,…连续按下相同按钮的行为类似于“1”的例子。
但是,这个字符输入法有一个比较麻烦的行为。如果按下数字按钮后暂时不操作的话,就会被强制转换成平假名。也就是说,如果你连续按三次“1”,你就会得到“う”,但如果你每隔一段时间按三次“1”,你就会得到“あああ”。例如,当按下“111111”时,根据按下间隔时间的不同,输入的字符串可以是“あ”与可能是“ああああああ”。“111111111111”可能是“い”,可能是“ええいああ”,可能是“是”,也可能是12个“あ”。此外,当按下不同的数字按钮时,转换为平假名也会发生,因此“12345”很难被转换为字符串“あかさたな”。
好吧,我是小心翼翼地打的,所以我不认为我按错了按钮,但我不确定我能按到合适的时间间隔。很有可能发送了和真正想发送的信息不一样的东西。那么,可能发送了多少种字符串呢?

Input

输入由多个数据组成。

每个情况以以下格式给出。

string

输入的结尾由输入由“#”组成的行给出
字符串(string)最多包含100,000个介于0和9之间的数字。
字符串(string)长度大于10,000的输入不超过50个。
测试用例的文件大小保证为5 MB或更小。
此外,测试用例的数量不超过100个。
每个数字键可以输入的字符如下表所示。
数字输入对应的可能的文字

数字

可能的字符

可能字符数个数

1

あいうえお

5

2

かきくけこ

5

3

さしすせそ

5

4

たちつてと

5

5

なにぬねの

5

6

はひふへほ

5

7

まみむめも

5

8

やゆよ

3

9

らりるれろ

5

0

わをん

3

输出

字符串可能代表意思的数量,结果对100000007取模

输入样例

1
11
111111
111111111111
12345
11111111119999999999
11111111113333333333
11111111118888888888
11111111112222222222111111111
11111111110000000000444444444
11224111122411
888888888888999999999999888888888888999999999999999999
666666666666666777333333333338888888888
1111114444441111111444499999931111111222222222222888111111115555
#

输出样例

1
2
32
1856
1
230400
230400
156480
56217600
38181120
128
26681431
61684293
40046720

提示:

设f [i] 当有i个连续的1的方案数

对于f[i]来讲,将后k个1进行捆绑翻译为固定的汉字,显然当该行文字为5种时,最多从前5个转化过来。3种的从前三个转化过来。最后再加上一种把所有1识别为一个字的情况就好了

答案统计就是将连续的相同字符为一组然后相乘就好了

此题中的日文可简单理解为一种字符,例如以“1”代表‘a’,以“11”代表‘b’,那么“11”可能的结果有“aa”和“b”两种

1 1 1 1 1 1 1 | 1 f[i-1]
1 1 1 1 1 1 | 1 1 f[i-2]
1 1 1 1 1 | 1 1 1 f[i-3]
1 1 1 1 | 1 1 1 1 f[i-4]
1 1 1 | 1 1 1 1 1 f[i-5]
1 1 1 1 1 1 1 1 1 1

#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
#include <set>
#include <unordered_map>
#include <cstring>
#include <vector>
#include <map>
#include <algorithm>
#include <cmath>

using namespace std;
const int N = 1e6 + 100;
const int mod = 100000007;
typedef long long ll;
ll a5[N];
ll a3[N];
string s;

void ini() {
    for (int i = 1; i <= 5; i++) {
        a5[i] = pow(2, i - 1);
    }
    for (int i = 6; i <= 110000; i++) {
        for (int j = 1; j <= 5; j++) {
            a5[i] += a5[i - j];
            a5[i] %= mod;
        }
        a5[i]++;
        a5[i] %= mod;
    }
    for (int i = 1; i <= 3; i++) {
        a3[i] = pow(2, i - 1);
    }
    for (int i = 4; i <= 110000; i++) {
        for (int j = 1; j <= 3; j++) {
            a3[i] += a3[i - j];
            a3[i] %= mod;
        }
        a3[i]++;
        a3[i] %= mod;
    }
}

int cur = 0;
int len;

ll rdd() {
    char c = s[cur];
    int cnt = 0;
    while (cur < len && s[cur] == c) {
        cnt++;
        cur++;
    }
    if (c == '8' || c == '0') {
        return a3[cnt];
    } else {
        return a5[cnt];
    }
}

int solve() {
    cur = 0;
    len = s.length();
    ll ans = 1;
    while (cur < len) {
        ans *= rdd();
        ans %= mod;
    }
    cout << ans % mod << endl;
}

int main() {
    ini();
    while (cin >> s) {
        if (s == "#") break;
        solve();
    }
}