【BZOJ 3530】【SDOI 2014】数数
2017-01-19 15:39
441 查看
http://www.lydsy.com/JudgeOnline/problem.php?id=3530
上午gty的测试题,爆0了qwq
类似文本生成器那道题,把AC自动机的转移建出来,准确地说建出了一个Trie图,然后在上面dp就可以了。
这道题因为有小于等于n的限制,所以要用类似数位dp的方法,记录卡不卡上界两个状态来转移。
上午gty的测试题,爆0了qwq
类似文本生成器那道题,把AC自动机的转移建出来,准确地说建出了一个Trie图,然后在上面dp就可以了。
这道题因为有小于等于n的限制,所以要用类似数位dp的方法,记录卡不卡上界两个状态来转移。
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int N = 1203; int ch [10], tot = 1, end ; void insert(char *s) { int len = strlen(s), x, tmp = 1, f; for (int i = 0; i < len; ++i) { x = s[i] - '0'; if (ch[tmp][x]) tmp = ch[tmp][x]; else tmp = ch[tmp][x] = ++tot; } end[tmp] = 1; } int qu , fail ; void BFS() { int x, f, v, p = 0, q = 1; qu[1] = 1; while (p != q) { x = qu[++p]; for (int i = 0; i <= 9; ++i) if (v = ch[x][i]) { f = fail[x]; while (f && ch[f][i] == 0) f = fail[f]; fail[v] = f ? ch[f][i] : 1; qu[++q] = v; } } for (int i = 1; i <= q; ++i) { x = qu[i]; for (int i = 0; i <= 9; ++i) if (!ch[x][i]) ch[x][i] = ch[fail[x]][i]; } } char s , c ; int m, f1 , f2 , f3 , f4 , r ; const int p = 1000000007; int main() { scanf("%s", s + 1); scanf("%d", &m); for (int i = 1; i <= m; ++i) { scanf("%s", c); insert(c); } for (int i = 0; i < 10; ++i) if (ch[1][i] == 0) ch[1][i] = ++tot; BFS(); int *pre0 = f1, *pre1 = f2, *now0 = f3, *now1 = f4; int len = strlen(s + 1); for (int i = 1; i <= len; ++i) r[i] = s[i] - '0'; for (int tmp = 1; tmp <= len; ++tmp) { swap(pre0, now0); swap(pre1, now1); memset(now0, 0, sizeof(int) * (tot + 1)); memset(now1, 0, sizeof(int) * (tot + 1)); if (tmp == 1) { if (end[ch[1][r[tmp]]] == 0) (++now1[ch[1][r[tmp]]]) %= p; for (int i = r[tmp] - 1; i >= 1; --i) if (end[ch[1][i]] == 0) (++now0[ch[1][i]]) %= p; } else { for (int i = 9; i >= 1; --i) if (end[ch[1][i]] == 0) (++now0[ch[1][i]]) %= p; } for (int i = 2; i <= tot; ++i) { for (int j = 0; j < 10; ++j) if (end[ch[i][j]] == 0) (now0[ch[i][j]] += pre0[i]) %= p; if (end[ch[i][r[tmp]]] == 0) (now1[ch[i][r[tmp]]] += pre1[i]) %= p; for (int j = r[tmp] - 1; j >= 0; --j) if (end[ch[i][j]] == 0) (now0[ch[i][j]] += pre1[i]) %= p; } } int ans = 0; for (int i = 1; i <= tot; ++i) { ans = (ans + now0[i]) % p; ans = (ans + now1[i]) % p; } printf("%d\n", ans); return 0; }
相关文章推荐
- bzoj3530 [Sdoi2014]数数(AC自动机+数位DP)
- 【BZOJ3530】[Sdoi2014]数数 AC自动机+数位DP
- [BZOJ3530][Sdoi2014]数数(AC自动机+数位DP)
- BZOJ3530:[SDOI2014]数数——题解
- [bzoj3530][Sdoi2014]数数_AC自动机_数位dp
- BZOJ.3530.[SDOI2014]数数(AC自动机 数位DP)
- bzoj 3530: [Sdoi2014]数数
- 【BZOJ】【3530】【SDOI2014】数数
- BZOJ 3530: [Sdoi2014]数数 [AC自动机 数位DP]
- [BZOJ3530]-[Sdoi2014]数数-AC自动机+数位DP
- bzoj 3530: [Sdoi2014]数数
- BZOJ 3530 【Sdoi2014】 数数
- 【BZOJ3530】数数(SDOI2014)-AC自动机+数位DP
- [BZOJ3530] [Sdoi2014]数数 && AC自动机+dp
- [BZOJ]3530 [SDOI2014] 数数 AC自动机 + DP
- [BZOJ3530][SDOI2014]数数(AC自动机+数位dp)
- bzoj 3530: [Sdoi2014]数数 数位dp
- BZOJ3530 [SDOI2014]数数
- 【bzoj3530】【sdoi2014】【数数】【AC自动机+数位dp】
- [BZOJ3530][Sdoi2014]数数(AC自动机上数位DP)