zoukankan      html  css  js  c++  java
  • POJ 2778

    一道非常非常优秀的题目,学到了很多

    首先是进一步加深对于AC自动机理解,这种将自动机看作图的思路实在是太惊艳了。理解0理解1

    此外学习了快速幂的方法,效率显著提升。快速幂

    最后,关于高维数组和指针之间的关系,以及typedef具体用法进一步理解,还有指针、函数、数组三种声明的解析

    美中不足的是粗心临门一脚打印答案的时候,忘记这时候也要模运算,好在最终很快查出来这个问题

    #include <iostream>
    #include <algorithm>
    #include <queue>
    #include <string>
    #include <vector>
    #include <cstdio>
    #include <cstring>
    #include <cmath>
    #include <string>
    #include <stack>
    #include <map>
    #include <set>
    using namespace std;
    
    const int maxs= 105;
    const int maxl= 15;
    typedef long long MATRIX[maxs][maxs];
    typedef long long (*MATRIX_PTR)[maxs];
    
    char str[maxl];
    MATRIX pac, aux, res;
    MATRIX_PTR pb, pa, pr;
    map<char, int> idx;
    struct Trie
    {
    	int L, root;
    	int next[maxs][4], fail[maxs], tag[maxs];
    	MATRIX b_pac;
    	void Init()
    	{
    		L= 0;
    		root= NewNode();
    	}
    	int NewNode()
    	{
    		for (int i= 0; i< 4; ++i){
    			next[L][i]= -1;
    		}
    		tag[L++]= 0;
    		return L-1;
    	}
    	void insert(char buf[])
    	{
    		int lth= strlen(buf);
    		int now= root;
    		for (int i= 0; i< lth; ++i){
    			int id= idx.at(buf[i]);
    			if (-1== next[now][id]){
    				next[now][id]= NewNode();
    			}
    			now= next[now][id];
    		}
    		++tag[now];
    	}
    	void build()
    	{
    		queue<int> Q;
    		fail[root]= root;
    		int now;
    
    		for (int i= 0; i< 4; ++i){
    			if (-1== next[root][i]){
    				next[root][i]= root;
    			}
    			else{
    				fail[next[root][i]]= root;
    				Q.push(next[root][i]);
    			}
    		}
    
    		while (!Q.empty()){
    			now= Q.front();
    			Q.pop();
    			// attention here
    			if (!tag[now] && tag[fail[now]]){
    				tag[now]= 1;
    			}
    
    			for (int i= 0; i< 4; ++i){
    				if (-1== next[now][i]){
    					next[now][i]= next[fail[now]][i];
    				}
    				else{
    					fail[next[now][i]]= next[fail[now]][i]; 
    					Q.push(next[now][i]);
    				}
    			}
    		}
    	}
    	int setMatrix(MATRIX pac)
    	{
    		build();
    		for (int i= 0; i< L; ++i){
    			for (int j= 0; j< L; ++j){
    				b_pac[i][j]= 0;
    			}
    		}
    		for (int i= 0; i< L; ++i){
    			if (tag[i]){
    				continue;
    			}
    			for (int j= 0; j< 4; ++j){
    				++b_pac[i][next[i][j]];
    			}
    		}
    		int tot= 0;
    
    		for (int i= 0; i< L; ++i){
    			if (tag[i]){
    				continue;
    			}
    			int cnt= 0;
    			for (int j= 0; j< L; ++j){
    				if (!tag[j]){
    					pac[tot][cnt++]= b_pac[i][j];
    				}
    			}
    			++tot;
    		}
    		return tot;
    	}
    }ac;
    
    void MatMultiple(const MATRIX lhs, const MATRIX rhs, MATRIX res, const int tot)
    {
    	for (int i= 0; i< tot; ++i){
    		for (int j= 0; j< tot; ++j){
    			res[i][j]= 0;
    			for (int k= 0; k< tot; ++k){
    				res[i][j]+= lhs[i][k]*rhs[k][j];
    			}
    			res[i][j]%= 100000;
    		}
    	}
    }
    void FastPower(MATRIX base, MATRIX res, int power, const int tot)
    {
    	for (int i= 0; i< tot; ++i){
    		res[i][i]= 1;
    		for (int j= i+1; j< tot; ++j){
    			res[i][j]= res[j][i]= 0;
    		}
    	}
    
    	pb= base;
    	pa= aux;
    	pr= res;
    	while (power > 0){
    		if (power & 1){
    			 MatMultiple(pr, pb, pa, tot);
    			 swap(pa, pr);
    		}
    		power>>= 1;
    		MatMultiple(pb, pb, pa, tot);
    		swap(pa, pb);
    	}
    }
    int main(int argc, char const *argv[])
    {
    	int m, n;
    	idx.insert(make_pair('A', 0));
    	idx.insert(make_pair('T', 1));
    	idx.insert(make_pair('C', 2));
    	idx.insert(make_pair('G', 3));
    
    	scanf("%d %d", &m, &n);
    	ac.Init();
    	for (int i= 0; i< m; ++i){
    		scanf(" %s", str);
    		ac.insert(str);
    	}
    	int tot= ac.setMatrix(pac);
    	FastPower(pac, res, n, tot);
    	long long ans= 0;
    	for (int i= 0; i< tot; ++i){
    		ans+= pr[0][i];
    	}
    	printf("%lld", ans%100000);
    
    	return 0;
    }
    
  • 相关阅读:
    Hadoop笔记
    InnoDB存储引擎概述--文件,表,索引,锁,事务的原理与实现
    SpringCloud-Eureka
    spring boot启动报错Error starting ApplicationContext(未能配置数据源)
    SSM框架配置
    SpringMvc笔记
    MySql笔记-->3
    MySql笔记-->2
    MySql笔记 -->1
    C# Lambda表达式
  • 原文地址:https://www.cnblogs.com/Idi0t-N3/p/14713702.html
Copyright © 2011-2022 走看看