zoukankan      html  css  js  c++  java
  • zoj 3494:BCD Code

    Description

    Binary-coded decimal (BCD) is an encoding for decimal numbers in which each digit is represented by its own binary sequence. To encode a decimal number using the common BCD encoding, each decimal digit is stored in a 4-bit nibble:

    Decimal:    0     1     2     3     4     5     6     7     8     9
    BCD:     0000  0001  0010  0011  0100  0101  0110  0111  1000  1001
    

    Thus, the BCD encoding for the number 127 would be:

     0001 0010 0111
    

    We are going to transfer all the integers from A to B, both inclusive, with BCD codes. But we find that some continuous bits, named forbidden code, may lead to errors. If the encoding of some integer contains these forbidden codes, the integer can not be transferred correctly. Now we need your help to calculate how many integers can be transferred correctly.

    Input

    There are multiple test cases. The first line of input is an integer T ≈ 100 indicating the number of test cases.

    The first line of each test case contains one integer N, the number of forbidden codes ( 0 ≤ N ≤ 100). Then N lines follow, each of which contains a 0-1 string whose length is no more than 20. The next line contains two positive integers A and B. Neither A or B contains leading zeros and 0 < A ≤ B < 10200.

    Output

    For each test case, output the number of integers between A and B whose codes do not contain any of the N forbidden codes in their BCD codes. For the result may be very large, you just need to output it mod 1000000009.

    Sample Input

    3
    1
    00
    1 10
    1
    00
    1 100
    1
    1111
    1 100
    

    Sample Output

    3
    9
    98

    还是太怂了啊……终究还是只能照着CZL的标程写出来……gg啦
    先预处理出AC自动机上某个节点在它后面加上[0...9]这些数字之后会到达哪一个节点或者不能添加该数字,然后就是普通数位dp了
    #include<queue>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    
    int read_p,read_ca;
    inline int read(){
        read_p=0;read_ca=getchar();
        while(read_ca<'0'||read_ca>'9') read_ca=getchar();
        while(read_ca>='0'&&read_ca<='9') read_p=read_p*10+read_ca-48,read_ca=getchar();
        return read_p;
    }
    const int LO=2,MOD=1000000009;
    inline void M(int &ans){
        if (ans>=MOD) ans-=MOD;
    }
    struct tree{
        int f;
        bool w;
        int t[LO],v[LO];
    }t[2001];
    char s[10001],n,m,tt;
    bool us[2001];
    int map[2001][10],f[2001][202],ti[2001][202];
    int num=0;
    queue <int> q;
    inline void in(){
        int m=strlen(s),p=0;
        for (int i=0;i<m;i++){
            if (!t[p].t[s[i]-48]) t[p].t[s[i]-48]=++num;
            p=t[p].t[s[i]-48];
        }
        t[p].w=1;
    }
    inline void mafa(){
        q.push(0);int k,p;t[0].f=0;
        while (!q.empty()){
            k=q.front();q.pop();
            for (int i=0;i<LO;i++)
            if (t[k].t[i]){
                p=t[k].f;
                while ((!t[p].t[i])&&p) p=t[p].f;
                t[t[k].t[i]].f=(k==p)?0:t[p].t[i];
                q.push(t[k].t[i]);
            }
        }
    }
    inline void ro(){
        int i,j,p;
        for (i=0;i<=num;i++)
        for (j=0;j<LO;j++)
        if (t[i].t[j]) t[i].v[j]=t[i].t[j];else{
            p=t[i].f;
            while ((!t[p].t[j])&&p) p=t[p].f;
            t[i].v[j]=t[p].t[j];
        }
    }
    inline void dfs(int x){
        if (us[x]) return;
        us[x]=1;
        if (t[x].w) return;
        dfs(t[x].f);
        t[x].w|=t[t[x].f].w;
    }
    inline void ju(){
        int i,j,k,p;
        for (i=0;i<=num;i++)
        if (!t[i].w)
        for (j=0;j<10;j++){
            p=i;
            for (k=3;k>=0;k--){
                p=t[p].v[((1<<k)&j)>0];
                if (t[p].w) break;
            }
            if (t[p].w) map[i][j]=-1;else map[i][j]=p;
        }
    }
    inline void FI(){
        for (int i=0;i<=num;i++) t[i].w=t[i].f=us[i]=0;
        for (int i=0;i<=num;i++)
        for (int j=0;j<LO;j++)
        t[i].t[j]=t[i].v[j]=0;
        num=0;us[0]=1;
    }
    inline void add(){
        int m=strlen(s),i;
        for (i=m-1;i>=0;i--) if (s[i]!='9') break;
        if (i>=0){
            s[i]++;for (i++;i<m;i++) s[i]='0';
        }else{
            s[0]='1';for (i=1;i<=m;i++) s[i]='0';s[m+1]=0;
        }
    }
    inline int ss(int x,int y){
        if (y==0) return 1;
        if (ti[x][y]==tt) return f[x][y];
        ti[x][y]=tt;
        int ans=0;
        for (int i=0;i<10;i++) if (map[x][i]!=-1)
        M(ans+=ss(map[x][i],y-1));
        return f[x][y]=ans;
    }
    inline int an(){
        int ans=0;
        int i,j,p,m=strlen(s);
        for (i=0;i<m;i++) s[i]-=48;
        for (i=1;i<m;i++) for (j=1;j<10;j++) if (map[0][j]!=-1) M(ans+=ss(map[0][j],i-1));
        for(i=1;i<s[0];i++)if(map[0][i]!=-1) M(ans+=ss(map[0][i],m-1));
        p=map[0][s[0]];
        for (i=1;i<m&&p!=-1;i++){
            for (j=0;j<s[i];j++) if (map[p][j]!=-1) M(ans+=ss(map[p][j],m-i-1));
            p=map[p][s[i]];
        }
        return ans;
    }
    inline void work(){
        int ans;
        FI();
        n=read();
        for (int i=1;i<=n;i++) scanf("%s",s),in();
        mafa();for (int i=1;i<=num;i++)dfs(i);ro();ju();
        scanf("%s",s);ans=an();
        scanf("%s",s);add();ans=an()-ans;
        printf("%d
    ",(ans<0?ans+MOD:ans));
    }
    int main(){
        for (tt=read();tt;tt--) work();
    }
    View Code
  • 相关阅读:
    java客户端集成RocketMq
    java8常见流式操作
    Spring源码架构以及编译
    Rocket消息存储原理
    由二叉树中序和先序遍历求二叉树的结构
    10.14重写ENqUEUE和DEQUEUE,使之能处理队列的下溢和上溢。
    10.12 说明如何用一个数组A[1..n]来实现两个栈,使得两个栈中的元素总数不到n时,两者都不会发生上溢,注意PUSH和POP操作的时间应为O(1)。
    用类模板实现对任何类型的数据进行堆栈进行存取操作。
    java struts2+urlrewrite 配置404错误
    c++ sizeof 及别名定义2种示例
  • 原文地址:https://www.cnblogs.com/Enceladus/p/5334885.html
Copyright © 2011-2022 走看看