http://poj.org/problem?id=1625

题意:

给出一些单词,求长度为m的串不包含这些单词的个数。

思路:

这道题和HDU 2243和POJ 2778是一样的,不同的是这道题不取模,所以不可以用矩阵快速幂,必须使用高精度,所以这里用滚动dp解决即可。

高精度的写法参考了kuangbin巨巨的模板。

 #include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<vector>
#include<stack>
#include<queue>
#include<cmath>
#include<map>
#include<set>
using namespace std;
typedef long long ll;
const int INF = 0x3f3f3f3f;
const int maxn=+; int n, m, num, p, len;
map<char,int> mp;
char s[]; struct Trie
{
int son[];
int cnt;
int fail;
}t[*]; struct Matrix
{
int mat[][], n;
Matrix(){}
Matrix(int _n)
{
n=_n;
for(int i=;i<n;i++)
for(int j=;j<n;j++)
mat[i][j]=;
}
}; void init(int x)
{
t[x].fail=;
t[x].cnt=;
memset(t[x].son,,sizeof(t[x].son));
} void trie(char *s)
{
int n=strlen(s);
int x=;
for(int i=;i<n;i++)
{
int c=mp[s[i]];
if(!t[x].son[c])
{
num++;
init(num);
t[x].son[c]=num;
}
x=t[x].son[c];
}
t[x].cnt=;
} void buildAC()
{
queue<int> Q;
for(int i=;i<=len;i++) if(t[].son[i]) Q.push(t[].son[i]);
while(!Q.empty())
{
int x=Q.front(); Q.pop();
int fail=t[x].fail;
for(int i=;i<=len;i++)
{ int y=t[x].son[i];
if(y)
{
t[y].fail=t[fail].son[i];
t[y].cnt|=t[t[fail].son[i]].cnt; //这儿很重要,这个标记需要传递
Q.push(y);
}
else t[x].son[i]=t[fail].son[i];
}
}
} Matrix getMatrix()
{
Matrix c=Matrix(num+);
for(int i=;i<=num;i++)
{
for(int j=;j<=len;j++)
{
if(t[t[i].son[j]].cnt==) c.mat[i][t[i].son[j]]++;
}
}
return c;
} /******************************高精度算法************************************/
struct BigInt
{
const static int mod = ;
const static int DLEN = ;
int a[],len;
BigInt()
{
memset(a,,sizeof(a));
len = ;
}
BigInt(int v)
{
memset(a,,sizeof(a));
len = ;
do
{
a[len++] = v%mod;
v /= mod;
}while(v);
}
BigInt(const char s[])
{
memset(a,,sizeof(a));
int L = strlen(s);
len = L/DLEN;
if(L%DLEN)len++;
int index = ;
for(int i = L-;i >= ;i -= DLEN)
{
int t = ;
int k = i - DLEN + ;
if(k < )k = ;
for(int j = k;j <= i;j++)
t = t* + s[j] - '';
a[index++] = t;
}
}
BigInt operator +(const BigInt &b)const
{
BigInt res;
res.len = max(len,b.len);
for(int i = ;i <= res.len;i++)
res.a[i] = ;
for(int i = ;i < res.len;i++)
{
res.a[i] += ((i < len)?a[i]:)+((i < b.len)?b.a[i]:);
res.a[i+] += res.a[i]/mod;
res.a[i] %= mod;
}
if(res.a[res.len] > )res.len++;
return res;
}
BigInt operator *(const BigInt &b)const
{
BigInt res;
for(int i = ; i < len;i++)
{
int up = ;
for(int j = ;j < b.len;j++)
{
int temp = a[i]*b.a[j] + res.a[i+j] + up;
res.a[i+j] = temp%mod;
up = temp/mod;
}
if(up != )
res.a[i + b.len] = up;
}
res.len = len + b.len;
while(res.a[res.len - ] == &&res.len > )res.len--;
return res;
}
void output()
{
printf("%d",a[len-]);
for(int i = len-;i >= ;i--)
printf("%04d",a[i]);
printf("\n");
}
};
/*************************************************************************/ BigInt dp[][]; int main()
{
//freopen("in.txt","r",stdin);
scanf("%d%d%d",&n,&m,&p);
mp.clear();
scanf("%s",s+);
len=strlen(s+);
for(int i=;i<=len;i++) mp[s[i]]=i;
for(int i=;i<=p;i++)
{
scanf("%s",s);
trie(s);
}
buildAC();
Matrix a=getMatrix(); //滚动数组实现
int now = ;
dp[now][] = ;
for(int i=;i<a.n;i++) dp[now][i] = ;
for(int i=;i<m;i++)
{
now^=;
for(int j=;j<a.n;j++) dp[now][j] = ;
for(int j=;j<a.n;j++)
for(int k=;k<a.n;k++)
if(a.mat[j][k] > ) dp[now][k] = dp[now][k]+dp[now^][j]*a.mat[j][k];
}
BigInt ans = ;
for(int i = ;i < a.n;i++)
ans = ans + dp[now][i];
ans.output();
return ;
}

最新文章

  1. 【BZOJ】2237: [NCPC2009]Flight Planning
  2. 主机名链接数据库,无法生成 SSPI 上下文
  3. 『信息收集』GoogleHacking快速定位目标网站
  4. sql多表查询之一:Where 和 On的秘密
  5. 如何修改vsftpd的默认根目录/var/ftp/pub到另一个目录?
  6. Win10专业版下图片拖到PS无法打开的解决技巧
  7. Android中显示和隐式Intent的使用
  8. angular-单页面应用程序
  9. HQL count(*)
  10. datetime处理日期和时间
  11. WebGIS裁剪算法-线裁剪多边形
  12. firedac调用ORACLE的存储过程
  13. XE4 for ios 谨慎处理字符串
  14. In file included from adlist.c:34:0: zmalloc.h:50:31: 致命错误:jemalloc/jemalloc.h:没有那个文件或目录
  15. 解决安装macports更新失败问题
  16. Jquery+Ajax实现Select动态添加数据
  17. Windows网络编程系列教程之四:Select模型
  18. Vue(4)- 获取原生的DOM的方式、DIY脚手架、vue-cli的使用
  19. Hadoop2.7.1安装与配置
  20. 关于No Dialect mapping for JDBC type :-9 hibernate执行原生sql语句问题

热门文章

  1. react-native 完整实现登录功能
  2. vue学习之webpack
  3. POJ3414—Pots(bfs加回溯)
  4. GET &#39;https://dl.google.com/dl/android/maven2/com/android/tools/build/gradle/3.1.2/gradle-3
  5. C语言标准函数源代码
  6. ZOJ 3949 Edge to the Root
  7. 神经网络 java包
  8. EditPlus 中文版停止更新
  9. EditPlus 4.3.2543 中文版已经发布(2月3日更新,Emmet 功能回归)
  10. office word 2010 怎么把左侧的标题大纲调出来?