- Solution
//本代码压掉后两维 #include<cstdio> #define max(a,b) (a<b?b:a) using namespace std; inline void read(int &x){ register char ch=getchar();x=0; while(ch<'0'||ch>'9') ch=getchar(); while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar(); } const int N=205,M=505; const int mod=1e9+7; int n,m,K,cnt=1,a[N],b[N];int bfs[N]; int v[N],fail[N],next[N][20],trans[N][20]; int f[N][N][M]; inline void insert(int l){ int x,now=1; for(int i=1;i<=l;i++){ read(x); if(!next[now][x]) next[now][x]=++cnt; now=next[now][x]; } read(x);v[now]+=x; } inline void build_AC(){ int l=0,r=0,x,y; for(int i=0;i<m;i++){ if(next[1][i]){ x=next[1][i]; fail[x]=1; trans[1][i]=x; bfs[++r]=x; } else{ trans[1][i]=1; } } while(l!=r){ x=bfs[++l]; v[x]+=v[fail[x]]; for(int i=0,p;i<m;i++){ if(next[x][i]){ y=next[x][i]; for(p=fail[x];p&&!next[p][i];p=fail[p]); if(p) fail[y]=next[p][i]; else fail[y]=1; trans[x][i]=y; bfs[++r]=y; } else{ for(p=fail[x];p&&!next[p][i];p=fail[p]); if(p) trans[x][i]=next[p][i]; else trans[x][i]=1; } } } } inline void Plus(int &x,int y){ x+=y; if(x>=mod) x-=mod; } inline void prep(int bit){//无任何限制预处理 for(int i=1;i<=cnt;i++) f[0][i][0]=1; for(int i=1;i<=bit;i++){ for(int j=1;j<=cnt;j++){ for(int p=0,x;p<m;p++){ x=trans[j][p]; for(int k=v[x];k<=K;k++){ Plus(f[i][j][k],f[i-1][x][k-v[x]]); } } } } } inline int work(int *a,bool flag){ int x,y,w,ans=0; //取出最高位后,保证无前导零后,无限制 for(int i=1;i<a[0];i++){ for(int j=1;j<m;j++){ y=trans[1][j]; w=v[y]; for(int k=w;k<=K;k++){ Plus(ans,f[i-1][y][k-w]); } } } //走一遍上界,要保证无前导零 x=1;w=0; for(int i=1;i<=a[0];i++){ for(int j=(i==1);j<a[i];j++){ y=trans[x][j]; for(int k=0;k<=K-(w+v[y]);k++){ Plus(ans,f[a[0]-i][y][k]); } } x=trans[x][a[i]]; w+=v[x]; } if(flag){//上界有否取 if(w<=K) Plus(ans,1); } return ans; } int main(){ read(n);read(m);read(K); read(a[0]);for(int i=1;i<=a[0];i++) read(a[i]); read(b[0]);for(int i=1;i<=b[0];i++) read(b[i]); for(int i=1,l;i<=n;i++) read(l),insert(l); build_AC();prep(max(a[0],b[0])); printf("%d ",(work(b,1)-work(a,0)+mod)%mod); return 0; }