hdu 2243 AC自动机 + 矩阵快速幂

//	hdu 2243 AC自动机 + 矩阵快速幂
//
//	题目大意:
//
//		给你一些短串,问在长度不超过k的任意串,包含至少一个这些短串的其中
//	一个.问这样的串有多少个.
//
//	解题思路:
//
//		首先, 包含和不包含是一种互斥关系,包含+不包含 = 全集u.全集的答案就是
//		26 ^ 1 + 26 ^ 2 + .... + 26 ^ k.不包含的比较好求.构建一个自动机,得到
//		一个转移矩阵A.表示状态i能到状态j的方法数.而这些状态中都是不包含所给的
//		串的.我们对这个矩阵进行k次幂,得到的矩阵的第一行的和,就是长度为k的不包
//		含串的的总数.我们要求的是A + A ^ 2 + A ^ 3 +.... + A ^ k.之后的部分就是
//		矩阵的再次构造.对于矩阵	| A  E |					
//
//					| 0  E | 对其求n次方,得到	
//
//					| A^n    1 + A + A^2 +...+A^(n-1)	|
//					| 0				E	|
//		对于这一题,我们增加一维构成全是1.即列全是1,行全是0除了处在最后一列上的除外.
//		对于26是一样的求法即	| 26 1 |					
//					| 0  1 | 对其求n次方,得到	
//
//					| 26^n	1 + 26 + 26 ^ 2 + ... + 26^(n-1)|
//					|	0			1	|
//		这样最后的答案就是全集 - 不包含.(矩阵写的搓,望各位体谅一二 (^ - ^)
//
//	感悟:
//
//		这道题,重点的思维还是在于补集的思想.将不好求的问题转化为好求的问题.自动机的
//		构建通过poj2778已经经历了一定程度的锤炼,不成问题.矩阵的构造也是问题不大,关键
//		是矩阵的n次方的求和.本来有一道裸地矩阵n次方求和,兴奋的学了学大牛的二分思想,
//		结果爆栈了,加了扩充栈以后,tle了...好吧,乖乖地再次构造一个矩阵,添加一维,然后
//		就过了,瞬间觉得矩阵太美妙了~~~~总的来说,这道题还是不错的,继续加油吧~~~FIGHTING
				

//#pragma comment(linker, "/STACK:1024000000,1024000000")
#include 
#include 
#include 
#include 
#include 

using namespace std;

typedef unsigned long long ull;
const int MAX_N = 66;
const int SIGMA = 26;
//;const ull MOD = (ull)1 << 64;
struct Matrix {
	int r,c;
	ull mat[MAX_N][MAX_N];
}res;


struct Aho_Corasick{
	int ch[MAX_N][SIGMA];
	int f[MAX_N];
	int last[MAX_N];;
	bool val[MAX_N];
	int sz;

	void init(){
		memset(ch[0],-1,sizeof(ch[0]));
		f[0] = 0;
		last[0] = 0;
		sz = 1;
	}

	int idx(char c){
		return c - 'a';
	}

	void insert(char *s){
		int n = strlen(s);
		int u = 0;
		for (int i=0;i que;
		for (int c=0;c>=1;
	}
	return ans;
}

//Matrix sigma_Matrix(Matrix res,int k){    // 二分求 A + A^2 + A^3 + ... + A^n
//	if (k == 1)	return res;
//	Matrix B = Power(res,(k+1)/2);
//	Matrix C = sigma_Matrix(res,k/2);
//	if (k&1){
//		return Add(res,Multiply(Add(res,B),C));
//	}else {
//		return Multiply(Add(Power(res,0),B),C);
//	}
//}

ull Power_Int(ull a,int b){
	ull res = 1;
	while(b){
		if (b & 1)
			res = res * a;
		a = a * a;
		b >>= 1;
	}
	return res;
}

//ull sigma_Int(ull a,int k){	// 二分 求整数 x + x^2 + x^3 + ... + x^n
//	if (k==1)	return a;
//	ull b = Power_Int(a,(k+1)/2);
//	ull c = sigma_Int(a,k/2);
//
//	//printf("b = %llu c = %llu k = %d\n",b,c,k);
//	if (k & 1){
//		return a + (a + b) * c;
//	}else {
//		return (1 + b) * c;
//	}
//}
//

//void print(){
//	for (int i=0;i

你可能感兴趣的:(Data,structure,hdu)