gggyt  
没谁离不开谁
/*  gyt
       Live up to every day            */
#include<cstdio>
#include<cmath>
#include<iostream>
#include<algorithm>
#include<vector>
#include<stack>
#include<cstring>
#include<queue>
#include<set>
#include<string>
#include<map>
#include <time.h>
#define PI acos(-1)
using namespace std;
typedef long long ll;
typedef double db;
const int maxn = 6000005;
const ll maxm = 1e7;
const ll mod = 1e9 + 7;
const int INF = 0x3f3f3f;
const ll inf = 1e15 + 5;
const db eps = 1e-9;
const int kind=26;
char ch[2505][1105];
int vis[3000],n;
struct Node{
    int key,cnt;
    struct Node *next[kind],*fail;
    Node(){
        key=0;
        for(int i=0;i<kind;i++)
        next[i]=0;
    }
}*root;

int Index(char c){
    return c-'A';
}
void insert(char *s,int t){
    int i=0;
    Node *p=root;
    while(s[i]){
        if(p->next[Index(s[i])]==0){
            p->next[Index(s[i])]=new Node();
        }
        p=p->next[Index(s[i])];
        i++;
    }
    p->key=1;
    p->cnt=t;
}
void build_fail() {
    root->fail=root;
    queue<Node *> q;
    q.push(root);
    while(!q.empty()){
        Node *t=q.front();q.pop();
        Node *p=0;
        for(int i=0;i<kind;i++){
            if(t->next[i]!=0){
                if(t==root)  t->next[i]->fail = root;
                else{
                    p=t->fail;
                    while(p!=root&&p->next[i]==0) p=p->fail;
                    if(p->next[i]) {
                        t->next[i]->fail=p->next[i];
                    }
                    else  t->next[i]->fail=root;
                }
                q.push(t->next[i]);
            }
        }
    }
}
int bfs(char *s){
    int i=0,sum=0,len=strlen(s);
    Node *p=root;
    while(s[i]){
        int pos=s[i]-'A';
        while(p->next[Index(s[i])]==0&&p!=root){
            p=p->fail;
        }
         p=p->next[pos];
        if (!p)  p=root;
        Node *t=p;
        while(t!=root&&t->key!=-3){
            if(abs(t->key)==1&&vis[t->cnt]){
                vis[t->cnt]=0;
            }
            t->key=-3;
            t=t->fail;
        }
        i++;
    }
}
int query1(char *s){
    int i=0,sum=0;
    Node *p=root;
    while(s[i]){
        int pos=s[i]-'A';
        while(p->next[Index(s[i])]==0&&p!=root){
            p=p->fail;
        }
         p=p->next[pos];
        if (!p)  p=root;
        Node *t=p;
        while(t!=root&&t->key!=-4){
            if(abs(t->key)==1)
            sum+=1;
            t->key=-4;
            t=t->fail;
        }
        i++;
    }
    return sum;
}
int query(char *s){
    int i=0,sum=0;
    Node *p=root;
    while(s[i]){
        int pos=s[i]-'A';
        while(p->next[Index(s[i])]==0&&p!=root){
            p=p->fail;
        }
         p=p->next[pos];
        if (!p)  p=root;
        Node *t=p;
        while(t!=root&&t->key>=0){
            if(t->key==1){
                vis[t->cnt]=1;
                t->key=-1;
            }
            else t->key=-2;
            t=t->fail;
        }
        i++;
    }
    for(int i=1;i<=n;i++)
        if(vis[i]){
            bfs(ch[i]);
            insert(ch[i],i);
        }
    sum=query1(s);
    return sum;
}
char str1[5100009],str2[5100009];

void solve(){
    int m,tt,i,j;
    memset(vis,0,sizeof(vis));
    root=new Node();
    scanf("%d", &n);
    for(int t=1;t<=n;t++){
        scanf("%s", str1+1);
        for(i=1, j=1; str1[i]; i++)
        {
            if(str1[i]>='A' && str1[i]<='Z') str2[j++] = str1[i];
            else
            {
                i++;
                int k = str1[i]-'0';i++;
                while(str1[i]<'A' || str1[i]>'Z') k = k*10+ str1[i++]-'0';
                while(k--) str2[j++] = str1[i];
                i++;
            }
        }
        str2[j] = '\0';
        strcpy(ch[t],str2+1);
        insert(str2+1,t);
    }
    build_fail();
    scanf("%s", str1+1);
    for(i=1, j=1; str1[i]; i++){
        if(str1[i]>='A' && str1[i]<='Z') str2[j++] = str1[i];
        else{
            i++;
            int k = str1[i]-'0';i++;
            while(str1[i]<'A' || str1[i]>'Z') k = k*10+ str1[i++]-'0';
            while(k--) str2[j++] = str1[i];
            i++;
        }
    }
    str2[j] = '\0';
    int ans = query(str2+1);
    printf("%d\n", ans);
}
int main() {
    int t = 1;
   // freopen("in.txt", "r", stdin);
    scanf("%d", &t);
    while(t--)
        solve();
    return 0;
}

 

posted on 2017-08-11 10:33  gggyt  阅读(171)  评论(0编辑  收藏  举报