首页 > 代码库 > [BZOJ3530][Sdoi2014]数数
[BZOJ3530][Sdoi2014]数数
阿拉~好像最近总是做到 AC 自动机的题目呢喵~
题目的算法似乎马上就能猜到的样子…… AC 自动机 + 数位 dp
先暴力转移出 f[i][j] :表示从 AC 自动机上第 j 号节点走 i 步且不碰到匹配串的方案数
然后直接用数位 dp 一位一位的试就可以了,大家都会吧~
但是…… 有前导 0 的情况真尼玛蛋疼啊!
忽的灵光一闪……
前导 0 仅能影响长度小于 L 的数的统计
那么所有长度 <L 的数全部专门暴力统计一边不就可以了!我真是特么太机智了喵~ O(∩_∩)O~
虽然有个 O(10*L*l) 的转移 但是只跑了 272 ms 呢
1 #include <cstdio> 2 #include <cstring> 3 #define ord(ch) ((ch)-‘0‘) 4 const int sizeOfLength=1201; 5 const int sizeOfNumber=1501; 6 const int sizeOfType=10; 7 const int mod=1000000007; 8 9 struct node 10 { 11 int idx; 12 bool end; 13 node * fail, * ch[sizeOfType]; 14 }; 15 node * dfa; 16 node memory[sizeOfNumber], * port=memory; 17 inline node * newnode(); 18 inline void insert(char * , int); 19 node * q[sizeOfNumber]; int l, r; 20 inline void build(); 21 inline void dynamicprogramming(); 22 23 char N[sizeOfLength]; int L; 24 int M; 25 int f[sizeOfLength][sizeOfNumber]; 26 char s[sizeOfNumber]; int len; 27 inline int getint(); 28 inline int getstr(char * ); 29 inline void putint(int); 30 31 int main() 32 { 33 int ans=0; 34 bool find=true; 35 node * t; 36 37 L=getstr(N); 38 M=getint(); 39 dfa=newnode(); 40 for (int i=1;i<=M;i++) 41 { 42 len=getstr(s); 43 insert(s, len); 44 } 45 build(); 46 dynamicprogramming(); 47 48 t=dfa; 49 for (int i=0;i<L;i++) 50 { 51 for (int j=(i==0);j<ord(N[i]);j++) if (!t->ch[j]->end) 52 ans=(ans+f[L-i-1][t->ch[j]->idx])%mod; 53 t=t->ch[ord(N[i])]; 54 if (t->end) 55 { 56 find=false; 57 break; 58 } 59 } 60 for (int i=L-2;i>=0;i--) 61 for (int j=1;j<=9;j++) 62 ans=(ans+f[i][dfa->ch[j]->idx])%mod; 63 64 putint(ans+find); 65 66 return 0; 67 } 68 inline int getint() 69 { 70 register int num=0; 71 register char ch; 72 do ch=getchar(); while (ch<‘0‘ || ch>‘9‘); 73 do num=num*10+ch-‘0‘, ch=getchar(); while (ch>=‘0‘ && ch<=‘9‘); 74 return num; 75 } 76 inline int getstr(char * str) 77 { 78 register int len=0; 79 register char ch; 80 do ch=getchar(); while (ch<‘0‘ || ch>‘9‘); 81 do str[len++]=ch, ch=getchar(); while (ch>=‘0‘ && ch<=‘9‘); 82 return len; 83 } 84 inline void putint(int num) 85 { 86 char stack[11]; 87 register int top=0; 88 for ( ;num;num/=10) stack[++top]=num%10+‘0‘; 89 for ( ;top;top--) putchar(stack[top]); 90 putchar(‘\n‘); 91 } 92 inline node * newnode() 93 { 94 node * ret=port++; 95 ret->idx=port-memory-1; 96 ret->fail=NULL; 97 memset(ret->ch, 0, sizeof ret->ch); 98 return ret; 99 }100 inline void insert(char * s, int l)101 {102 node * t=dfa;103 for (int i=0;i<l;i++)104 {105 if (!t->ch[ord(s[i])]) t->ch[ord(s[i])]=newnode();106 t=t->ch[ord(s[i])];107 }108 t->end=true;109 }110 inline void build()111 {112 dfa->fail=dfa;113 for (int i=0;i<sizeOfType;i++)114 if (dfa->ch[i])115 {116 dfa->ch[i]->fail=dfa;117 q[r++]=dfa->ch[i];118 }119 else120 dfa->ch[i]=dfa;121 for ( ;l<r;l++)122 {123 node * u=q[l];124 u->end|=u->fail->end;125 for (int i=0;i<sizeOfType;i++)126 if (u->ch[i])127 {128 u->ch[i]->fail=u->fail->ch[i];129 q[r++]=u->ch[i];130 }131 else132 u->ch[i]=u->fail->ch[i];133 }134 }135 inline void dynamicprogramming()136 {137 int tot=port-memory;138 for (int i=0;i<tot;i++)139 if (!(dfa+i)->end)140 f[0][(dfa+i)->idx]=1;141 for (int i=1;i<=L;i++)142 for (int j=0;j<tot;j++) if (!(dfa+j)->end)143 for (int k=0;k<sizeOfType;k++)144 f[i][(dfa+j)->idx]=(f[i][(dfa+j)->idx]+f[i-1][(dfa+j)->ch[k]->idx])%mod;145 }
[BZOJ3530][Sdoi2014]数数
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。