| Time Limit: 5000MS | Memory Limit: 10000K | |
| Total Submissions: 7469 | Accepted: 2023 |
Description
Input
Output
Sample Input
2 3 1 ab bb
Sample Output
5
题意:给定n个字符,p个禁止出现的序列,求长度为m的合法序列有多少个。
解题思路很简单,不过这个题计算结果不是取模,只能高精度,wa多次,tle,mle都出现了,过得比较艰难。
代码:
/* ***********************************************
Author :xianxingwuguan
Created Time :2014-2-5 11:29:37
File Name :3.cpp
************************************************ */
#pragma comment(linker, "/STACK:102400000,102400000")
#include <stdio.h>
#include <iostream>
#include <algorithm>
#include <sstream>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#include <string>
#include <time.h>
#include <math.h>
#include <queue>
#include <stack>
#include <set>
#include <map>
using namespace std;
#define INF 0x3f3f3f3f
#define eps 1e-8
#define pi acos(-1.0)
typedef long long ll;
map<char,int> mp;
int n;
struct BigInt
{
const static int mod = 10000;
const static int DLEN = 4;
int a[110],len;
BigInt()
{
memset(a,0,sizeof(a));
len = 1;
}
BigInt(int v)
{
memset(a,0,sizeof(a));
len = 0;
do
{
a[len++] = v%mod;
v /= mod;
}while(v);
}
BigInt(const char s[])
{
memset(a,0,sizeof(a));
int L = strlen(s);
len = L/DLEN;
if(L%DLEN)len++;
int index = 0;
for(int i = L-1;i >= 0;i -= DLEN)
{
int t = 0;
int k = i - DLEN + 1;
if(k < 0)k = 0;
for(int j = k;j <= i;j++)
t = t*10 + s[j] - ‘0‘;
a[index++] = t;
}
}
BigInt operator +(const BigInt &b)const
{
BigInt res;
res.len = max(len,b.len);
for(int i = 0;i <= res.len;i++)
res.a[i] = 0;
for(int i = 0;i < res.len;i++)
{
res.a[i] += ((i < len)?a[i]:0)+((i < b.len)?b.a[i]:0);
res.a[i+1] += res.a[i]/mod;
res.a[i] %= mod;
}
if(res.a[res.len] > 0)res.len++;
return res;
}
BigInt operator *(const BigInt &b)const
{
BigInt res;
for(int i = 0; i < len;i++)
{
int up = 0;
for(int j = 0;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 != 0)
res.a[i + b.len] = up;
}
res.len = len + b.len;
while(res.a[res.len - 1] == 0 &&res.len > 1)res.len--;
return res;
}
void output()
{
printf("%d",a[len-1]);
for(int i = len-2;i >=0 ;i--)
printf("%04d",a[i]);
printf("\n");
}
}dp[110][110];
struct Trie{
int next[110][70],end[110],fail[110];
int root,L;
int newnode(){
for(int i=0;i<n;i++)
next[L][i]=-1;
end[L++]=0;
return L-1;
}
void init(){
L=0;
root=newnode();
}
void insert(char *str){
int len=strlen(str);
int now=root;
for(int i=0;i<len;i++){
int p=mp[str[i]];
if(next[now][p]==-1)
next[now][p]=newnode();
now=next[now][p];
}
end[now]|=1;
}
void build(){
queue<int> q;
fail[root]=root;
for(int i=0;i<n;i++)
if(next[root][i]==-1)
next[root][i]=root;
else {
fail[next[root][i]]=root;
q.push(next[root][i]);
}
while(!q.empty()){
int now=q.front();
q.pop();
end[now]|=end[fail[now]];
for(int i=0;i<n;i++)
if(next[now][i]==-1)
next[now][i]=next[fail[now]][i];
else {
fail[next[now][i]]=next[fail[now]][i];
q.push(next[now][i]);
}
}
}
void solve(int m){
for(int i=0;i<=m;i++)
for(int j=0;j<=L;j++)
dp[i][j]=BigInt(0);
dp[0][0]=BigInt(1);
for(int i=0;i<m;i++)
for(int j=0;j<L;j++){
for(int k=0;k<n;k++){
int p=next[j][k];
if(end[p])continue;
dp[i+1][p]=dp[i][j]+dp[i+1][p];
}
}
BigInt ans=BigInt(0);
for(int i=0;i<L;i++)
ans=ans+dp[m][i];
ans.output();
}
}ac;
char str[10000];
int main()
{
//freopen("data.in","r",stdin);
//freopen("data.out","w",stdout);
int i,j,k,m,p;
while(~scanf("%d%d%d",&n,&m,&p)){
ac.init();mp.clear();
getchar();
gets(str);
for(i=0;i<n;i++)
mp[str[i]]=i;
while(p--){
gets(str);
ac.insert(str);
}
ac.build();
ac.solve(m);
}
return 0;
}
原文:http://blog.csdn.net/xianxingwuguan1/article/details/18938841