BCD Code [ZOJ 3494]

http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=4317

有可能error串包含相互的error串,所以建立fail的时候val的标记也要相互转移。

View Code
typedef long long ll;
ll N;
#define mod 1000000009 
#define debug puts("wrong");
#define ROOT 0
const int MAX_NODE=2222;//stringnum*stringlen
const int CHI=2; //儿子数
ll dp[222][MAX_NODE];
ll num[222], cnt;
char a[222], b[222];

struct ACtree {
    ll size;
    ll val[MAX_NODE];
    ll fail[MAX_NODE];
    ll SQ[MAX_NODE];
    ll chd[MAX_NODE][CHI];

    void init() {
        size=fail[0]=0;
        memset(val,0,sizeof(val));
        memset(chd[0],0,sizeof(chd));
    }
    void insert(char *str,ll k) {
        ll i,j,id,p=ROOT;
        for(i=0;str[i];i++) {
            id=str[i]-'0';
            if(!chd[p][id]) {
                chd[p][id]=++size;
                memset(chd[size],0,sizeof(chd[size]));
            }
            p=chd[p][id];
        }
        val[p]=k;
    }
    void build() {
        ll i,j,k,id,p=ROOT,r,v;
        ll qhead,qtail;
        qhead=qtail=0;
        for(i=0;i<CHI;i++) {
            if(chd[p][i]) {
                SQ[qtail++]=chd[p][i];
                fail[chd[p][i]]=ROOT;
            }
        }
        while(qhead!=qtail) {
            r=SQ[qhead++];
            for(i=0;i<CHI;i++) {
                v=chd[r][i]; 
                if(v) {
                    SQ[qtail++]=v,fail[v]=chd[fail[r]][i];
                    val[v]|=val[fail[v]]; //有可能error串包含相互的error串 
                }
                else chd[r][i]=chd[fail[r]][i];
            }
        }
    }
}AC;

void get_data() {
    char str[100]; AC.init();
    scanf("%lld",&N);
    for(ll i=1;i<=N;i++) {
        scanf("%s",str);
        AC.insert(str,i);
    }
}
void sub() {
    ll len=strlen(a),i;
    for(i=len-1;i>=0 && a[i]=='0';i--) a[i]='9';
    a[i]--;
}
ll gao(ll x,ll y) {
    for(int i=3;i>=0;i--) {
        ll tmp=(x&(1<<i))?1:0;
        y=AC.chd[y][tmp];
        if(AC.val[y]) return -1;
    }
    return y;
}
ll dfs(ll le,ll state,bool less,bool ok) {
    if(le==-1) return 1;
    if(ok&&!less && dp[le][state]!=-1) return dp[le][state];
    ll res=0, tmp=state, d, e=less?num[le]:9;
    for(d=0;d<=e;d++) {
        if(ok||d) tmp=gao(d,state);
        if(tmp!=-1) res+=dfs(le-1,tmp,less&&d==e,ok||d);
        res%=mod; 
    } 
    if(ok&&!less) dp[le][state]=res;
    return res;
}
ll cal(char*str) {
    ll len=strlen(str),i;
    cnt=0;
    for(i=len-1;i>=0;i--) num[cnt++]=str[i]-'0';
//    for(i=0;i<cnt;i++) printf("%d ",num[i]); printf("\n"); 
    return dfs(cnt-1,0,true,false);
}
void solve() {  
    ll ans=0;
    AC.build();
   scanf("%s%s",a,b);
   sub();
   memset(dp,-1,sizeof(dp));
   ans=cal(b)-cal(a); 
   printf("%lld\n",(ans%mod+mod)%mod);
}
int main() {
    int ca; scanf("%d",&ca);
    while(ca--) get_data(),solve(); 
    return 0;
}
原文地址:https://www.cnblogs.com/zhang1107/p/3072168.html