zoukankan      html  css  js  c++  java
  • UVALive 5103 Computer Virus on Planet Pandora Description 一些新兴需求模式的字符串 AC自己主动机

    主题链接:点击打开链接

    题意:

    case数

    n个模式串

    一个母串。

    问:n个模式串出现的种数(一个模式串多次出现仅仅算一次)

    对于 "ABC" , 若母串出现了"CBA"这种反串。也算出现了。

    所以:

    1

    ABC

    CBA 

    ans = 1

    #include <cstdio>
    #include <cstring>
    #include <cmath>
    #include <queue>
    #include <algorithm>
    using namespace std;
    const int maxnode = 250*1000+10000;
    const int sigma_size = 26;
    
    struct Trie{
    	int ch[maxnode][sigma_size];
    	int val[maxnode];	 //该单词在模式串中出现的次数
    	int last[maxnode];
    	int f[maxnode];		 //失配数组
    	int num[maxnode];	 //该单词出如今文本串的次数
    	int pre[maxnode];    //该单词的前驱
    	int len[maxnode];    //以该单词结尾的单词长度
    	int Char[maxnode];	 //该单词相应的字母
    	int road[maxnode];   //路径压缩优化 针对计算模式串出现的种数
    	int sz;
    	int Newnode()
    	{
    	    val[sz] = f[sz] = last[sz] = len[sz] = num[sz] = 0;
    	    memset(ch[sz], 0, sizeof ch[sz]);
    	    return sz++;
        }
    	void init(){
    	    sz=0;
    	    Newnode();
    	}
    	int idx(char c){ return c-'A'; }
    	int insert(char *s){
    		int u = 0;
    		for(int i = 0, c; s[i] ;i++){
    			c = idx(s[i]);
    			if(!ch[u][c])
    				ch[u][c] = Newnode();
    			pre[ch[u][c]] = u;
    			Char[ch[u][c]] = s[i];
    			len[ch[u][c]] = len[u]+1;
    			road[ch[u][c]] = 1;
    			u = ch[u][c];
    		}
    		val[u] = 1;
    		num[u] = 0;
    		return u;
    	}
       void getFail(){
            queue<int> q;
            for(int i = 0; i<sigma_size; i++)
                if(ch[0][i]) q.push(ch[0][i]);
            int r, c, u, v;
            while(!q.empty()){
                r = q.front(); q.pop();
                for(c = 0; c<sigma_size; c++){
                    u = ch[r][c];
                    if(!u)continue;
                    q.push(u);
                    v = f[r];
                    while(v && ch[v][c] == 0) v = f[v]; //沿失配边走上去 假设失配后有节点 且 其子节点c存在则结束循环
                    f[u] = ch[v][c];
                }
            }
        }
    	void find(char *T){
        //计算模式串出现的个数:(每种多次出现算多次)
    		int j = 0;
    		for(int i = 0, c, temp; T[i] ; i++){
    			c = idx(T[i]);
    			while(j && ch[j][c]==0) j = f[j];
    			j = ch[j][c];
    
    			temp = j;
    			while(temp){
                    num[temp]++;
                    temp = f[temp];
                }
            }
        }
        void find_kind(char *T, int &ans){
        //计算种数, 反复出现的不再计算(若多个询问则要在此处加for(i=0->sz)lu[i]=1;
    		int j = 0, i, c, temp;
    		for(i = 0; T[i]; i++){
    			c = idx(T[i]);
    			while(j && ch[j][c] == 0) j = f[j];
    			j = ch[j][c];
    			temp = j;
    			while(temp && road[temp]){
    				if(val[temp])
                    {
    					++ans;
    					val[temp] = 0;
    				}
                    road[temp] = 0;
                    temp = f[temp];
                }
            }
        }
    }ac;
    char s[1015], a[5100010], b[5100010], c;
    int n, num;
    int main() {
    	int T; scanf("%d", &T);
    	while (T-->0) {
    		ac.init();
    		scanf("%d", &n);
    		while(n--){
    			scanf("%s", s);
    			ac.insert(s);
    		}
    		ac.getFail();
    		int top = 0;
    		scanf("%s", a);
    		int i = 0;
    		while(a[i]){
    			if(a[i]!='[')
    				b[top++] = a[i];
    			else {
    				num = 0;
    				i++;
    				while( '0' <= a[i] && a[i] <= '9')
    					num = num*10 + a[i]-'0', i++;
    				c = a[i];
    				i++;
    				while(num-- > 0){
    					b[top++] = c;
    				}
    			}
    			i++;
    		}
    		a[top] = b[top] = 0;
    		for(int i = top-1; i >= 0; i--)a[i] = b[top-i-1];
    		int ans = 0;
    		ac.find_kind(b, ans);
    		ac.find_kind(a, ans);
    		printf("%d
    ", ans);
    	}
    	return 0;
    }
    


    版权声明:本文博主原创文章,博客,未经同意不得转载。

  • 相关阅读:
    plsql记住登录密码
    java之通过反射,来获得某对象的所有方法(类方法提取器)
    java之RTTI和反射的理解
    Thinking in java之正则表达式小例子
    java正则表达式之java小爬虫
    【ACM】Binary String Matching
    PHP var_export
    PHP FPM
    【ACM】阶乘之和
    【ACM】最少乘法次数
  • 原文地址:https://www.cnblogs.com/blfshiye/p/4818213.html
Copyright © 2011-2022 走看看