ZOJ 3494 BCD Code - AC自动机 - 数位dp
2018-02-08 11:23
417 查看
没有传送门
没有题目大意
AC自动机维护数位dp模板题
从一位神犇那里get到了一中不特判前导0姿势
我真是愚蠢晚期
真是愚蠢晚期
愚蠢晚期
晚期
没有题目大意
AC自动机维护数位dp模板题
从一位神犇那里get到了一中不特判前导0姿势
我真是愚蠢晚期
真是愚蠢晚期
愚蠢晚期
晚期
#include<iostream> #include<cstring> #include<cstdio> #include<algorithm> #include<queue> #define mod 1000000009 #define N 110 #define LEN 210 #define TN 2010 #define toi(c) (c-'0') #define debug(x) cerr<<#x<<"="<<x #define sp <<" " #define ln <<endl using namespace std; struct ac_node{ int ch[2],fail;bool val; }t[TN];int ac_node_cnt; char A[LEN],B[LEN];bool ban[TN]; int a[LEN],b[LEN],dp[LEN][TN][2]; int can[TN][15],f[LEN][TN]; inline int new_ac_node() { int x=++ac_node_cnt;t[x].fail=0,t[x].val=0; return t[x].ch[0]=t[x].ch[1]=0,ac_node_cnt; } inline int solve(int x,int a) { if(ban[x]) return 0; for(int i=3;i>=0;i--) { x=t[x].ch[(a&(1<<i))>>i]; if(ban[x]) return 0; } return x; } inline int get_can(int m) { for(int i=1;i<=m;i++) for(int j=0;j<=9;j++) can[i][j]=solve(i,j); return 0; } inline int init_f(int n) { int m=ac_node_cnt; for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) f[i][j]=0; for(int i=1,y;i<=9;i++) if((y=can[1][i])) f[1][y]++; for(int i=1;i<n;i++) for(int j=1;j<=m;j++) if(!ban[j]&&f[i][j]) for(int k=0,y;k<=9;k++) if((y=can[j][k])) (f[i+1][y]+=f[i][j])%=mod; return 0; } inline int get_ans(int *a,int n) { // for(int i=1;i<=n;i++) cout<<a[i];cout<<endl; if(!n) return 0; int m=ac_node_cnt,ans=0; for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) dp[i][j][0]=dp[i][j][1]=0; for(int i=1,y;i<=a[1];i++) if((y=can[1][i])) dp[1][y][i==a[1]]++; for(int i=1,y;i<n;i++) for(int x=1;x<=m;x++) if(!ban[x]) for(int j=0;j<=9;j++) if((y=can[x][j])) { if(dp[i][x][0]) (dp[i+1][y][0]+=dp[i][x][0])%=mod;//,debug(i)sp,debug(x)sp,debug(i+1)sp,debug(y)ln; if(dp[i][x][1]&&j<=a[i+1]) (dp[i+1][y][j==a[i+1]]+=dp[i][x][1])%=mod;//,debug(i)sp,debug(x)sp,debug(i+1)sp,debug(y)sp,debug((j==a[i+1]))ln; } /* for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) debug(i)sp,debug(j)sp,debug(dp[i][j][0])sp,debug(dp[i][j][1])ln;*/ for(int i=1;i<=m;i++) if(!ban[i]) (ans+=dp [i][0])%=mod,(ans+=dp [i][1])%=mod; /* for(int i=1;i<n;i++) for(int j=1;j<=m;j++) debug(i)sp,debug(j)sp,debug(f[i][j])ln;*/ for(int i=1;i<n;i++) for(int j=1;j<=m;j++) if(!ban[j]) (ans+=f[i][j])%=mod; return ans; } inline int insert_ac(int rt,char *s,int n) { int x=rt; for(int i=1;i<=n;i++) { int c=toi(s[i]); if(!t[x].ch[c]) t[x].ch[c]=new_ac_node(); x=t[x].ch[c]; } t[x].val=true;return 0; } queue<int> q; struct edges{ int to,pre; }e[TN<<1];int etop,h[TN]; inline int add_edge(int u,int v) { return e[++etop].to=v,e[etop].pre=h[u],h[u]=etop; } inline int get_fail(int rt) { while(!q.empty()) q.pop(); for(int i=0;i<=1;i++) { int &x=t[rt].ch[i]; if(x) t[x].fail=rt,q.push(x),add_edge(rt,x); else x=rt; } while(!q.empty()) { int x=q.front();q.pop(); for(int i=0;i<=1;i++) { int &y=t[x].ch[i],f=t[x].fail,c=t[f].ch[i]; if(y) t[y].fail=c,q.push(y),add_edge(c,y); else y=c; } } /* for(int i=1;i<=ac_node_cnt;i++) debug(i)sp,debug(t[i].ch[0])sp,debug(t[i].ch[1])ln;*/ return 0; } inline int get_ban(int x,bool flag) { for(int i=h[x];i;i=e[i].pre) get_ban(e[i].to,flag|t[e[i].to].val); return ban[x]=flag; } int main() { int T;scanf("%d",&T); while(T--) { int x,n,al,bl,rt;scanf("%d",&n); ac_node_cnt=0,rt=new_ac_node(); for(int i=1;i<=n;i++) scanf("%s",A+1),insert_ac(rt,A,(int)strlen(A+1)); memset(h,0,sizeof(h)),etop=0; get_fail(rt),get_ban(rt,false),scanf("%s%s",A+1,B+1); al=(int)strlen(A+1),bl=(int)strlen(B+1); for(int i=1;i<=al;i++) a[i]=A[i]-'0'; for(int i=1;i<=bl;i++) b[i]=B[i]-'0'; a[x=al]--;while(a[x]<0) a[x]+=10,a[--x]--; if(!a[1]) { for(int i=2;i<=al;i++) a[i-1]=a[i]; al--; } get_can(ac_node_cnt),init_f(max(al,bl)); printf("%d\n",(get_ans(b,bl)-get_ans(a,al)+mod)%mod); } return 0; }
相关文章推荐
- ZOJ 3494 BCD Code (AC自动机+数位DP,5级)
- ZOJ 3494 BCD Code(AC自动机+数位DP)
- ZOJ 3494 BCD Code(自动机+数位DP)
- zoj 3494 BCD Code (ac自动机+数位dp)
- ZOJ 3494 BCD Code (AC自动机+数位DP)
- ZOJ 3494 BCD Code (*AC自动机+数位DP 待整理)
- ZOJ3494 BCD Code-AC自动机+数位DP
- ZOJ 3494 BCD Code(AC自动机+数位DP)
- zoj 3494 BCD Code (ac自动机+数位dp)
- zoj 3494 BCD Code(AC自动机+数位dp)
- 【AC自动机+数位DP】【zoj 3494】BCD Code
- [AC自动机+数位dp] zoj 3494 BCD Code
- ZOJ - 3494 BCD Code(AC自动机+数位DP)
- ZOJ 3494 BCD Code (AC自动机+数位DP,5级)
- ZOJ 3494 BCD Code(AC自动机+数位DP)
- ZOJ 3494 BCD Code (AC自动机 + 数位DP)
- zoj 3494(ac自动机+数位dp)
- ZOJ 3494 BCD Code AC自动机 + 数位DP
- zoj 3494 BCD Code AC自动机 + 数位dp
- 【ZOJ】3494 BCD Code AC自动机+数位DP