Codeforces 433E

来源:互联网 发布:mac如何转换音频格式 编辑:程序博客网 时间:2024/06/16 12:48
/*************************麻婆豆腐AC自动机 + 数位dp好题!每个字符串都有一个权值,如果一个数字串中出现该串那么该数字串就的权值就加上字符串的权值,求区间内数字串权值小于等于给定值的数量。AC自动机状态转移,数位dp枚举每一位。再统计符合条件状态数。**********************/#include <cstdio>#include <queue>#include <cstring>#include <iostream>using namespace std;#define maxn 500010struct Trie{    int next[maxn][26],fail[maxn];    int end[maxn];    int root,L;    int newNode(){        for(int i=0;i<26;i++) next[L][i] = -1;        end[L++] = 0;        return L-1;    }    void init(){        L = 0;        root = newNode();    }    void insert(int str[],int len,int val){        //printf("insert:%s\n",str);        int now = root;        for(int i=0;i<len;i++){            int temp = str[i];            if(next[now][temp] == -1){                next[now][temp] = newNode();            }            now = next[now][temp];        }        end[now] += val;    }    void build(){        queue<int> que;        fail[root] = root;        for(int i=0;i<26;i++){            if( next[root][i] == -1){                next[root][i] = root;            }else{                fail[next[root][i]] = root;                que.push(next[root][i]);            }        }        while(!que.empty()){            int now = que.front();            que.pop();            end[now] += end[fail[now]];            for(int i=0;i<26;i++){                int t = next[now][i];                if(t==-1){                    next[now][i] = next[fail[now]][i];                }else{                    fail[t] = next[fail[now]][i];                    //printf("id:%d fail:%d\n",t,fail[t]);                    que.push(t);                }            }        }    }    void debug(){        for(int i=0;i<L;i++){            printf("id:%3d fail:%3d end:%3d next:[",i,fail[i],end[i]);            for(int j=0;j<26;j++){                printf(" %2d",next[i][j]);            }            printf("]\n");        }    }}ac;////////////////////////////////////////////////////typedef long long LL;const int mod = 1000000007;int n,m,k;int len[2];int p[2][250];int bit[250];int buf[250];LL dp[210][420][520];LL dfs(int h,int s,int now,bool flag, bool zero){    now -= ac.end[s];    if(now < 0) return 0;    if(h==-1) {        //cout << sum << " " << now << endl;        return 1;    }    if(!flag && dp[h][s][now] != -1) return dp[h][s][now];    LL res = 0;    if(zero){        res += dfs(h-1,s,now,flag && bit[h]==0,true);        res %= mod;    }else{        res += dfs(h-1,ac.next[s][0],now,flag && bit[h]==0,false);        res %= mod;    }    int up = flag?bit[h]:m-1;    for(int i=1;i<=up;i++){        res += dfs(h-1,ac.next[s][i],now,flag && i==up,false);        res %= mod;    }    if(!flag && !zero) dp[h][s][now] = res;    return res;}LL solve(){    for(int i=0;i<len[0];i++) bit[i] = p[0][i];    //for(int i=0;i<len[0];i++) cout << bit[i];    //cout << endl;    LL ans = -dfs(len[0]-1,0,k,true,true);    //cout << ans << endl;    for(int i=0;i<len[1];i++) bit[i] = p[1][i];    //for(int i=0;i<len[1];i++) cout << bit[i];    //cout << endl;    memset(dp,-1,sizeof(dp));    ans += dfs(len[1]-1,0,k,true,true);    ans = (ans%mod + mod)%mod;    return ans;}int main(){    while(cin >> n >> m >> k){        scanf("%d",&len[0]);        for(int i=0;i<len[0];i++) scanf("%d",&p[0][len[0] - i - 1]);        // l-1        for(int i=0;i<len[0];i++){            if(p[0][i] == 0) p[0][i] = m-1;            else{                p[0][i]--;                break;            }        }        scanf("%d",&len[1]);        for(int i=0;i<len[1];i++) scanf("%d",&p[1][len[1] - i - 1]);        ac.init();        memset(dp,-1,sizeof(dp));        int t,temp,v;        while(n--){            scanf("%d",&t);            for(int i=0;i<t;i++) scanf("%d",&buf[i]);            scanf("%d",&v);            ac.insert(buf,t,v);        }        ac.build();        //ac.debug();        cout << solve() << endl;    }    return 0;}


0 0
原创粉丝点击